diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 8d7b3bf..e1c3c66 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1335,17 +1335,23 @@ include_dir 'conf.d'
        </para>
 
        <para>
-        At present, this feature is supported only on Linux. The setting is
-        ignored on other systems when set to <literal>try</literal>.
+        At present, this feature is supported only on Linux and Windows. The
+        setting is ignored on other systems when set to <literal>try</literal>.
        </para>
 
        <para>
         The use of huge pages results in smaller page tables and less CPU time
-        spent on memory management, increasing performance. For more details,
+        spent on memory management, increasing performance. For more details on Linux,
         see <xref linkend="linux-huge-pages">.
        </para>
 
        <para>
+        This feature uses the large-page support on Windows. To use the large-page
+        support, you need to assign Lock page in memory user right to the Windows
+        user account which runs <productname>PostgreSQL</productname>.
+       </para>
+
+       <para>
         With <varname>huge_pages</varname> set to <literal>try</literal>,
         the server will try to use huge pages, but fall back to using
         normal allocation if that fails. With <literal>on</literal>, failure
diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
index 0ff2c7e..88b195a 100644
--- a/src/backend/port/win32_shmem.c
+++ b/src/backend/port/win32_shmem.c
@@ -21,6 +21,7 @@ HANDLE		UsedShmemSegID = INVALID_HANDLE_VALUE;
 void	   *UsedShmemSegAddr = NULL;
 static Size UsedShmemSegSize = 0;
 
+static bool EnableLockPagesPrivilege(int elevel);
 static void pgwin32_SharedMemoryDelete(int status, Datum shmId);
 
 /*
@@ -103,6 +104,61 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
 	return true;
 }
 
+/*
+ * EnableLockPagesPrivilege
+ *
+ * Try to acquire SeLockMemoryPrivilege so we can use large pages.
+ */
+static bool
+EnableLockPagesPrivilege(int elevel)
+{
+	HANDLE hToken;
+	TOKEN_PRIVILEGES tp;
+	LUID luid;
+
+	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
+	{
+		ereport(elevel,
+				(errmsg("could not enable Lock pages in memory user right"),
+				 errdetail("Failed system call was %s, error code %lu", "OpenProcessToken", GetLastError())));
+		return FALSE;
+	}
+
+	if (!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &luid))
+	{
+		CloseHandle(hToken);
+		ereport(elevel,
+				(errmsg("could not enable Lock pages in memory user right"),
+				 errdetail("Failed system call was %s, error code %lu", "LookupPrivilegeValue", GetLastError())));
+		return FALSE;
+	}
+	tp.PrivilegeCount = 1;
+	tp.Privileges[0].Luid = luid;
+	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+
+	if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
+	{
+		ereport(elevel,
+				(errmsg("could not enable Lock pages in memory user right"),
+				 errdetail("Failed system call was %s, error code %lu", "AdjustTokenPrivileges", GetLastError())));
+		CloseHandle(hToken);
+		return FALSE;
+	}
+
+	if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
+	{
+		ereport(elevel,
+				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+				 errmsg("could not enable Lock pages in memory user right"),
+				 errhint("Assign Lock pages in memory user right to the Windows user account which runs PostgreSQL.")));
+		CloseHandle(hToken);
+		return FALSE;
+	}
+
+	CloseHandle(hToken);
+
+	return TRUE;
+}
 
 /*
  * PGSharedMemoryCreate
@@ -127,11 +183,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
 	int			i;
 	DWORD		size_high;
 	DWORD		size_low;
-
-	if (huge_pages == HUGE_PAGES_ON)
-		ereport(ERROR,
-				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-				 errmsg("huge pages not supported on this platform")));
+	SIZE_T		largePageSize = 0;
+	DWORD		flProtect = PAGE_READWRITE;
 
 	/* Room for a header? */
 	Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
@@ -140,6 +193,34 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
 
 	UsedShmemSegAddr = NULL;
 
+	if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY)
+	{
+		/* Does the processor support large pages? */
+		largePageSize = GetLargePageMinimum();
+		if (largePageSize == 0)
+		{
+			ereport(huge_pages == HUGE_PAGES_ON ? FATAL : DEBUG1,
+					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+					 errmsg("the processor does not support large pages")));
+			ereport(DEBUG1,
+					(errmsg("disabling huge pages")));
+		}
+		else if (!EnableLockPagesPrivilege(huge_pages == HUGE_PAGES_ON ? FATAL : DEBUG1))
+		{
+			ereport(DEBUG1,
+					(errmsg("disabling huge pages")));
+		}
+		else
+		{
+			/* Huge pages available and privilege enabled, so turn on */
+			flProtect = PAGE_READWRITE | SEC_COMMIT | SEC_LARGE_PAGES;
+
+			/* Round size up as appropriate. */
+			if (size % largePageSize != 0)
+				size += largePageSize - (size % largePageSize);
+		}
+	}
+
 #ifdef _WIN64
 	size_high = size >> 32;
 #else
@@ -163,7 +244,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port,
 
 		hmap = CreateFileMapping(INVALID_HANDLE_VALUE,	/* Use the pagefile */
 								 NULL,	/* Default security attrs */
-								 PAGE_READWRITE,		/* Memory is Read/Write */
+								 flProtect,
 								 size_high,		/* Size Upper 32 Bits	*/
 								 size_low,		/* Size Lower 32 bits */
 								 szShareMem);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 946ba9e..9659000 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -3796,7 +3796,7 @@ static struct config_enum ConfigureNamesEnum[] =
 
 	{
 		{"huge_pages", PGC_POSTMASTER, RESOURCES_MEM,
-			gettext_noop("Use of huge pages on Linux."),
+			gettext_noop("Use of huge pages on Linux/Windows."),
 			NULL
 		},
 		&huge_pages,
