diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 4e46451..27d669e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -7421,6 +7421,9 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
   <indexterm zone="libpq-pgservice">
    <primary>.pg_service.conf</primary>
   </indexterm>
+  <indexterm zone="libpq-pgservice">
+   <primary>pg_service.conf.d</primary>
+  </indexterm>
 
   <para>
    The connection service file allows libpq connection parameters to be
@@ -7444,6 +7447,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
   </para>
 
   <para>
+   Additional connection service files can be placed in the system-wide
+   directory <filename>`pg_config --sysconfdir`/pg_service.conf.d</filename>
+   or in the subdirectory <filename>pg_service.conf.d</filename> below the
+   directory specified by the environment variable
+   <envar>PGSYSCONFDIR</envar>.  These will have the lowest precedence,
+   following the files described above. Files beginning with '.' will be
+   ignored.
+  </para>
+
+  <para>
    The file uses an <quote>INI file</quote> format where the section
    name is the service name and the parameters are connection
    parameters; see <xref linkend="libpq-paramkeywords"/> for a list.  For
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8d54333..91ef22b 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -20,6 +20,7 @@
 #include <ctype.h>
 #include <time.h>
 #include <unistd.h>
+#include <dirent.h>
 
 #include "libpq-fe.h"
 #include "libpq-int.h"
@@ -400,6 +401,10 @@ static void defaultNoticeReceiver(void *arg, const PGresult *res);
 static void defaultNoticeProcessor(void *arg, const char *message);
 static int parseServiceInfo(PQconninfoOption *options,
 				 PQExpBuffer errorMessage);
+static int searchServiceFileDirectory(const char *service,
+						PQconninfoOption *options,
+						PQExpBuffer errorMessage,
+						bool *group_found);
 static int parseServiceFile(const char *serviceFile,
 				 const char *service,
 				 PQconninfoOption *options,
@@ -4542,10 +4547,15 @@ next_file:
 		goto last_file;
 
 	status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
-	if (status != 0)
+	if (group_found || status != 0)
 		return status;
 
 last_file:
+
+	status = searchServiceFileDirectory(service, options, errorMessage, &group_found);
+	if (status != 0)
+		return status;
+
 	if (!group_found)
 	{
 		printfPQExpBuffer(errorMessage,
@@ -4556,6 +4566,58 @@ last_file:
 	return 0;
 }
 
+/*
+ * searchServiceFileDirectory: Try to parse every file in pg_service.conf.d
+ * as a pg_service.conf style file.
+ *
+ * Returns 0 on success, nonzero on failure.
+ */
+static int
+searchServiceFileDirectory(const char *service,
+						   PQconninfoOption *options,
+						   PQExpBuffer errorMessage,
+						   bool *group_found)
+{
+	char			serviceDirPath[MAXPGPATH];
+	char			serviceFile[MAXPGPATH];
+	int				status;
+	struct stat		stat_buf;
+	struct dirent  *direntry;
+	DIR			   *serviceDir;
+
+	snprintf(serviceDirPath, MAXPGPATH, "%s/pg_service.conf.d",
+			 getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
+
+	if (stat(serviceDirPath, &stat_buf) != 0 || !S_ISDIR(stat_buf.st_mode))
+		return 0;
+
+	serviceDir = opendir(serviceDirPath);
+	if (serviceDir == NULL)
+		return 0;
+
+	while ((direntry = readdir(serviceDir)) != NULL)
+	{
+		if (direntry->d_name[0] == '.')
+			continue;
+
+		snprintf(serviceFile, MAXPGPATH, "%s/%s", serviceDirPath,
+				 direntry->d_name);
+
+		if (stat(serviceFile, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode)
+			|| access(serviceFile, R_OK))
+			continue;
+
+		status = parseServiceFile(serviceFile, service, options, errorMessage,
+								  group_found);
+		if (*group_found || status != 0)
+			break;
+	}
+
+	closedir(serviceDir);
+
+	return status;
+}
+
 static int
 parseServiceFile(const char *serviceFile,
 				 const char *service,
