diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index fe4893a..65d90fb 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -235,10 +235,10 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		/*
 		 * 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 fallback_application_name, client_encoding, guc, 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 *));
 
@@ -247,6 +247,8 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 									  keywords + n, values + n);
 		n += ExtractConnectionOptions(user->options,
 									  keywords + n, values + n);
+		n += ExtractGucOptions(server->options,
+									  keywords + n, values + n);
 
 		/* Use "postgres_fdw" as fallback_application_name. */
 		keywords[n] = "fallback_application_name";
@@ -286,6 +288,16 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 		/* Prepare new session for use */
 		configure_remote_session(conn);
 
+		/* Free memory for "options" parameter */
+		for (int i = 0; i < n; i++)
+		{
+			if (strcmp(keywords[i], "options") == 0)
+			{
+				pfree((void *)(values[i]));
+				break;
+			}
+		}
+
 		pfree(keywords);
 		pfree(values);
 	}
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index d912bd9..c529a00 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -8607,3 +8607,28 @@ SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700
 
 -- Clean-up
 RESET enable_partitionwise_aggregate;
+-- ===================================================================
+-- test for work_mem option
+-- ===================================================================
+BEGIN;
+CREATE SERVER workmem1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( work_mem '64kB' );
+SELECT count(*)
+FROM pg_foreign_server
+WHERE srvname = 'workmem1'
+AND srvoptions @> array['work_mem=64kB'];
+ count 
+-------
+     1
+(1 row)
+
+ALTER SERVER workmem1 OPTIONS( SET work_mem '8MB' );
+SELECT count(*)
+FROM pg_foreign_server
+WHERE srvname = 'workmem1'
+AND srvoptions @> array['work_mem=8MB'];
+ count 
+-------
+     1
+(1 row)
+
+ROLLBACK;
diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c
index 6854f1b..67adb79 100644
--- a/contrib/postgres_fdw/option.c
+++ b/contrib/postgres_fdw/option.c
@@ -22,7 +22,7 @@
 #include "commands/extension.h"
 #include "utils/builtins.h"
 #include "utils/varlena.h"
-
+#include "utils/guc.h"
 
 /*
  * Describes the valid options for objects that this wrapper uses.
@@ -32,6 +32,7 @@ typedef struct PgFdwOption
 	const char *keyword;
 	Oid			optcontext;		/* OID of catalog in which option may appear */
 	bool		is_libpq_opt;	/* true if it's used in libpq */
+	bool		is_guc_opt;	/* true if it's used for GUC setting */
 } PgFdwOption;
 
 /*
@@ -52,7 +53,7 @@ static PQconninfoOption *libpq_options;
 static void InitPgFdwOptions(void);
 static bool is_valid_option(const char *keyword, Oid context);
 static bool is_libpq_option(const char *keyword);
-
+static bool is_guc_option(const char *keyword);
 
 /*
  * Validate the generic options given to a FOREIGN DATA WRAPPER, SERVER,
@@ -143,6 +144,19 @@ postgres_fdw_validator(PG_FUNCTION_ARGS)
 						 errmsg("%s requires a non-negative integer value",
 								def->defname)));
 		}
+		else if (strcmp(def->defname, "work_mem") == 0)
+		{
+			int work_mem = 0;
+			bool result;
+			result = parse_int(defGetString(def), &work_mem, GUC_UNIT_KB, NULL);
+			if ((!result) || ((work_mem < 64) || (work_mem > MAX_KILOBYTES)))
+			{
+				ereport(ERROR,
+					(errcode(ERRCODE_SYNTAX_ERROR),
+					 errmsg("invalid value for option '%s'",
+							def->defname)));
+			}
+		}
 	}
 
 	PG_RETURN_VOID();
@@ -160,24 +174,27 @@ InitPgFdwOptions(void)
 
 	/* non-libpq FDW-specific FDW options */
 	static const PgFdwOption non_libpq_options[] = {
-		{"schema_name", ForeignTableRelationId, false},
-		{"table_name", ForeignTableRelationId, false},
-		{"column_name", AttributeRelationId, false},
+		{"schema_name", ForeignTableRelationId, false, false},
+		{"table_name", ForeignTableRelationId, false, false},
+		{"column_name", AttributeRelationId, false, false},
 		/* use_remote_estimate is available on both server and table */
-		{"use_remote_estimate", ForeignServerRelationId, false},
-		{"use_remote_estimate", ForeignTableRelationId, false},
+		{"use_remote_estimate", ForeignServerRelationId, false, false},
+		{"use_remote_estimate", ForeignTableRelationId, false, false},
 		/* cost factors */
-		{"fdw_startup_cost", ForeignServerRelationId, false},
-		{"fdw_tuple_cost", ForeignServerRelationId, false},
+		{"fdw_startup_cost", ForeignServerRelationId, false, false},
+		{"fdw_tuple_cost", ForeignServerRelationId, false, false},
 		/* shippable extensions */
-		{"extensions", ForeignServerRelationId, false},
+		{"extensions", ForeignServerRelationId, false, false},
 		/* updatable is available on both server and table */
-		{"updatable", ForeignServerRelationId, false},
-		{"updatable", ForeignTableRelationId, false},
+		{"updatable", ForeignServerRelationId, false, false},
+		{"updatable", ForeignTableRelationId, false, false},
 		/* fetch_size is available on both server and table */
-		{"fetch_size", ForeignServerRelationId, false},
-		{"fetch_size", ForeignTableRelationId, false},
-		{NULL, InvalidOid, false}
+		{"fetch_size", ForeignServerRelationId, false, false},
+		{"fetch_size", ForeignTableRelationId, false, false},
+		/* for GUC settings */
+		/* work_mem */
+		{"work_mem", ForeignServerRelationId, false, true},
+		{NULL, InvalidOid, false, false}
 	};
 
 	/* Prevent redundant initialization. */
@@ -241,6 +258,7 @@ InitPgFdwOptions(void)
 		else
 			popt->optcontext = ForeignServerRelationId;
 		popt->is_libpq_opt = true;
+		popt->is_guc_opt = false;
 
 		popt++;
 	}
@@ -289,6 +307,25 @@ is_libpq_option(const char *keyword)
 }
 
 /*
+ * Check whether the given option is one of the valid GUC options.
+ */
+static bool
+is_guc_option(const char *keyword)
+{
+	PgFdwOption *opt;
+
+	Assert(postgres_fdw_options);	/* must be initialized already */
+
+	for (opt = postgres_fdw_options; opt->keyword; opt++)
+	{
+		if (opt->is_guc_opt && strcmp(opt->keyword, keyword) == 0)
+			return true;
+	}
+
+	return false;
+}
+
+/*
  * Generate key-value arrays which include only libpq options from the
  * given list (which can contain any kind of options).  Caller must have
  * allocated large-enough arrays.  Returns number of options found.
@@ -319,6 +356,42 @@ ExtractConnectionOptions(List *defelems, const char **keywords,
 }
 
 /*
+ * Generate key-value arrays which include for GUC options from the
+ * given list (which can contain any kind of options).  Caller must have
+ * allocated large-enough arrays.  Returns number of options found.
+ */
+int
+ExtractGucOptions(List *defelems, const char **keywords,
+						 const char **values)
+{
+	ListCell   *lc;
+	bool is_guc = false;
+	StringInfoData buf;
+	static const char options[] = "options";
+
+	initStringInfo(&buf);
+
+	foreach(lc, defelems)
+	{
+		DefElem    *d = (DefElem *) lfirst(lc);
+
+		if (is_guc_option(d->defname))
+		{
+			is_guc = true;
+			appendStringInfo(&buf, " -c %s=%s ", d->defname, defGetString(d));
+		}
+	}
+	
+	if (is_guc)
+	{
+		keywords[0] = options;
+		values[0] = buf.data;
+	}
+
+	return (is_guc ? 1 : 0);
+}
+
+/*
  * Parse a comma-separated string and return a List of the OIDs of the
  * extensions named in the string.  If any names in the list cannot be
  * found, report a warning if warnOnMissing is true, else just silently
diff --git a/contrib/postgres_fdw/postgres_fdw.h b/contrib/postgres_fdw/postgres_fdw.h
index 70b538e..01e94a1 100644
--- a/contrib/postgres_fdw/postgres_fdw.h
+++ b/contrib/postgres_fdw/postgres_fdw.h
@@ -130,6 +130,9 @@ extern int ExtractConnectionOptions(List *defelems,
 						 const char **values);
 extern List *ExtractExtensionList(const char *extensionsString,
 					 bool warnOnMissing);
+extern int ExtractGucOptions(List *defelems,
+						 const char **keywords,
+						 const char **values);
 
 /* in deparse.c */
 extern void classifyConditions(PlannerInfo *root,
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index c0b0dd9..c450eca 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -2348,3 +2348,24 @@ SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700
 
 -- Clean-up
 RESET enable_partitionwise_aggregate;
+
+-- ===================================================================
+-- test for work_mem option
+-- ===================================================================
+BEGIN;
+
+CREATE SERVER workmem1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( work_mem '64kB' );
+
+SELECT count(*)
+FROM pg_foreign_server
+WHERE srvname = 'workmem1'
+AND srvoptions @> array['work_mem=64kB'];
+
+ALTER SERVER workmem1 OPTIONS( SET work_mem '8MB' );
+
+SELECT count(*)
+FROM pg_foreign_server
+WHERE srvname = 'workmem1'
+AND srvoptions @> array['work_mem=8MB'];
+
+ROLLBACK;
diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml
index 54b5e98..50a508e 100644
--- a/doc/src/sgml/postgres-fdw.sgml
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -313,6 +313,15 @@
      </listitem>
     </varlistentry>
 
+    <varlistentry>
+     <term><literal>work_mem</literal></term>
+     <listitem>
+      <para>
+       This option specifies the size of working memory using <xref linkend="guc-work-mem"/>.
+       The default value is depend on th remote instance setting.
+      </para>
+     </listitem>
+    </varlistentry>  
    </variablelist>
 
   </sect3>
