diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 82aa14a65d..da62b0f604 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -349,16 +349,20 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		const char **keywords;
 		const char **values;
 		int			n;
+		int			i;
+		StringInfoData buf;
 
 		/*
 		 * Construct connection params from generic options of ForeignServer
 		 * and UserMapping.  (Some of them might not be libpq options, in
-		 * which case we'll just waste a few array slots.)  Add 3 extra slots
-		 * for fallback_application_name, client_encoding, end marker.
+		 * which case we'll just waste a few array slots.)  Add 4 extra slots
+		 * for application_name, fallback_application_name, client_encoding,
+		 * end marker.
 		 */
-		n = list_length(server->options) + list_length(user->options) + 3;
+		n = list_length(server->options) + list_length(user->options) + 4;
 		keywords = (const char **) palloc(n * sizeof(char *));
 		values = (const char **) palloc(n * sizeof(char *));
+		initStringInfo(&buf);
 
 		n = 0;
 		n += ExtractConnectionOptions(server->options,
@@ -366,7 +370,26 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		n += ExtractConnectionOptions(user->options,
 									  keywords + n, values + n);
 
-		/* Use "postgres_fdw" as fallback_application_name. */
+		/* Use GUC paramter if set */
+		if (pgfdw_application_name && *pgfdw_application_name != '\0')
+		{
+			keywords[n] = "application_name";
+			values[n] = pgfdw_application_name;
+			n++;
+		}
+
+		/* Search application_name and replace it */
+		for (i = n - 1; i >= 0; i--)
+		{
+			if (strcmp(keywords[i], "application_name") == 0)
+			{
+				parse_application_name(&buf, values[i]);
+				values[i] = buf.data;
+				break;
+			}
+		}
+
+		/* Use "postgres_fdw" as fallback_application_name */
 		keywords[n] = "fallback_application_name";
 		values[n] = "postgres_fdw";
 		n++;
@@ -437,6 +460,7 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 
 		pfree(keywords);
 		pfree(values);
+		pfree(buf.data);
 	}
 	PG_CATCH();
 	{
diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
index c574ca2cf3..b9dfedf6c7 100644
--- a/contrib/postgres_fdw/option.c
+++ b/contrib/postgres_fdw/option.c
@@ -1,7 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * option.c
- *		  FDW option handling for postgres_fdw
+ *		  FDW and GUC option handling for postgres_fdw
  *
  * Portions Copyright (c) 2012-2021, PostgreSQL Global Development Group
  *
@@ -18,6 +18,9 @@
 #include "catalog/pg_user_mapping.h"
 #include "commands/defrem.h"
 #include "commands/extension.h"
+#include "common/string.h"
+#include "lib/stringinfo.h"
+#include "libpq/libpq-be.h"
 #include "postgres_fdw.h"
 #include "utils/builtins.h"
 #include "utils/guc.h"
@@ -52,6 +55,18 @@ static void InitPgFdwOptions(void);
 static bool is_valid_option(const char *keyword, Oid context);
 static bool is_libpq_option(const char *keyword);
 
+/*
+ * GUC parameters
+ */
+char* pgfdw_application_name = NULL;
+
+/*
+ * _PG_init() and check hook
+ */
+
+static bool check_pgfdw_application_name(char **newval, void **extra, GucSource source);
+void _PG_init(void);
+
 #include "miscadmin.h"
 
 /*
@@ -435,3 +450,118 @@ ExtractExtensionList(const char *extensionsString, bool warnOnMissing)
 	list_free(extlist);
 	return extensionOids;
 }
+
+/*
+ * parse application_name and set escaped string.
+ * This function is almost same as log_line_prefix(), but
+ * accepted escape sequence is different.
+ * 
+ * buf must be initialized.
+ */
+void
+parse_application_name(StringInfo buf, const char *name)
+{
+	int			padding;
+	const char *p;
+
+	for(p = name; *p != '\0'; p++)
+	{
+		if (*p != '%')
+		{
+			/* literal char, just copy */
+			appendStringInfoChar(buf, *p);
+			continue;
+		}
+
+		/* must be a '%', so skip to the next char */
+		p++;
+		if (*p == '\0')
+			break;				/* format error - ignore it */
+		else if (*p == '%')
+		{
+			/* string contains %% */
+			appendStringInfoChar(buf, '%');
+			continue;
+		}
+		if (*p > '9')
+			padding = 0;
+		else if ((p = process_padding(p, &padding)) == NULL)
+			break;
+
+		/* process the option */
+		switch (*p)
+		{
+			case 'a':
+				{
+					const char *appname = application_name;
+
+					if (*appname == '\0')
+						appname = "[unknown]";
+					if (padding != 0)
+						appendStringInfo(buf, "%*s", padding, appname);
+					else
+						appendStringInfoString(buf, appname);
+				}
+				break;
+			case 'u':
+				{
+					const char *username = MyProcPort->user_name;
+
+					if (padding != 0)
+						appendStringInfo(buf, "%*s", padding, username);
+					else
+						appendStringInfoString(buf, username);
+				}
+				break;
+			case 'd':
+				{
+					const char *dbname = MyProcPort->database_name;
+
+					if (padding != 0)
+						appendStringInfo(buf, "%*s", padding, dbname);
+					else
+						appendStringInfoString(buf, dbname);
+				}
+				break;
+			case 'p':
+				if (padding != 0)
+					appendStringInfo(buf, "%*d", padding, MyProcPid);
+				else
+					appendStringInfo(buf, "%d", MyProcPid);
+				break;
+			default:
+				/* format error - ignore it */
+				break;
+		}
+	}
+}
+
+/* 
+ * Completely same as server-side.
+ */
+static bool
+check_pgfdw_application_name(char **newval, void **extra, GucSource source)
+{
+	/* Only allow clean ASCII chars in the application name */
+	if (*newval)
+		pg_clean_ascii(*newval);
+	return true;
+}
+
+/*
+ * Define GUC parameters.
+ */
+void
+_PG_init(void)
+{
+	DefineCustomStringVariable("postgres_fdw.application_name",
+							   "Sets the application name. This is used when connects to the remote server.",
+							   NULL,
+							   &pgfdw_application_name,
+							   NULL,
+							   PGC_USERSET,
+							   GUC_IS_NAME,
+							   check_pgfdw_application_name,
+							   NULL,
+							   NULL);
+}
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index 9d443baf02..a4720f9e0a 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -318,6 +318,8 @@ typedef struct
  */
 PG_FUNCTION_INFO_V1(postgres_fdw_handler);
 
+void _PG_init(void);
+
 /*
  * FDW callback routines
  */
diff --git a/contrib/postgres_fdw/postgres_fdw.h b/contrib/postgres_fdw/postgres_fdw.h
index ca83306af9..1168ad4b52 100644
--- a/contrib/postgres_fdw/postgres_fdw.h
+++ b/contrib/postgres_fdw/postgres_fdw.h
@@ -158,6 +158,8 @@ extern int	ExtractConnectionOptions(List *defelems,
 									 const char **values);
 extern List *ExtractExtensionList(const char *extensionsString,
 								  bool warnOnMissing);
+extern void parse_application_name(StringInfo buf, const char *name);
+extern char *pgfdw_application_name;
 
 /* in deparse.c */
 extern void classifyConditions(PlannerInfo *root,
diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml
index 0075bc3dbb..437aed647a 100644
--- a/doc/src/sgml/postgres-fdw.sgml
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -105,6 +105,66 @@
   of columns to the remote table is by name, not position.
  </para>
 
+ <sect2>
+  <title> Configuration Parameters </title>
+  <variablelist>
+   <varlistentry>
+    <term>
+     <varname>postgres_fdw.application_name</varname> (<type>string</type>)
+     <indexterm>
+      <primary>
+       <varname>postgres_fdw.application_name</varname> configuration parameter
+      </primary>
+     </indexterm>
+    </term>
+    <listitem>
+     <para>
+      Specifies a value for <xref linkend="guc-application-name"/>
+      configuration parameter. This value is used only when a backend process
+      starts to establish the remote connection. 
+     </para>
+
+     <para>
+      Same as <xref linkend="guc-log-line-prefix"/>, this is a
+      <function>printf</function>-style string. Accepted escapes are
+      bit different from <xref linkend="guc-log-line-prefix"/>,
+      but padding can be used like as it.
+     </para>
+
+     <informaltable>
+      <tgroup cols="2">
+       <thead>
+        <row>
+         <entry>Escape</entry>
+         <entry>Effect</entry>
+        </row>
+       </thead>
+       <tbody>
+        <row>
+         <entry><literal>%a</literal></entry>
+         <entry>Application name</entry>
+        </row>
+        <row>
+         <entry><literal>%u</literal></entry>
+         <entry>Local user name</entry>
+        </row>
+        <row>
+         <entry><literal>%d</literal></entry>
+         <entry>Local database name</entry>
+        </row>
+        <row>
+         <entry><literal>%p</literal></entry>
+         <entry>Local backend process ID</entry>
+        </row>
+       </tbody>
+      </tgroup>
+     </informaltable>
+
+    </listitem>
+   </varlistentry>
+  </variablelist>
+ </sect2>
+
  <sect2>
   <title>FDW Options of postgres_fdw</title>
 
