diff -Nacr a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
*** a/doc/src/sgml/config.sgml	2016-09-20 05:17:08.000000000 +0900
--- b/doc/src/sgml/config.sgml	2016-09-26 11:38:01.000000000 +0900
***************
*** 1336,1352 ****
         </para>
  
         <para>
!         At present, this feature is supported only on Linux. 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,
          see <xref linkend="linux-huge-pages">.
         </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
--- 1336,1358 ----
         </para>
  
         <para>
!         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 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 -Nacr a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c
*** a/src/backend/port/win32_shmem.c	2016-09-20 05:17:08.000000000 +0900
--- b/src/backend/port/win32_shmem.c	2016-09-26 11:07:59.000000000 +0900
***************
*** 21,26 ****
--- 21,27 ----
  void	   *UsedShmemSegAddr = NULL;
  static Size UsedShmemSegSize = 0;
  
+ static bool EnableLockPagesPrivilege(int elevel);
  static void pgwin32_SharedMemoryDelete(int status, Datum shmId);
  
  /*
***************
*** 103,108 ****
--- 104,164 ----
  	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,137 ****
  	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")));
  
  	/* Room for a header? */
  	Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
--- 183,190 ----
  	int			i;
  	DWORD		size_high;
  	DWORD		size_low;
! 	SIZE_T		largePageSize = 0;
! 	DWORD		flProtect;
  
  	/* Room for a header? */
  	Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
***************
*** 140,145 ****
--- 193,235 ----
  
  	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")));
+ 			huge_pages = HUGE_PAGES_OFF;
+ 		}
+ 	}
+ 
+ 	if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY)
+ 	{
+ 		/* Enable Lock pages in memory user right. */
+ 		if (!EnableLockPagesPrivilege(huge_pages == HUGE_PAGES_ON ? FATAL : DEBUG1))
+ 		{
+ 			ereport(DEBUG1,
+ 					(errmsg("disabling huge pages")));
+ 			huge_pages = HUGE_PAGES_OFF;
+ 		}
+ 	}
+ 
+ 	if (huge_pages == HUGE_PAGES_ON || huge_pages == HUGE_PAGES_TRY)
+ 	{
+ 		flProtect = PAGE_READWRITE | SEC_COMMIT | SEC_LARGE_PAGES;
+ 
+ 		/* Round size up as appropriate. */
+ 		if (size % largePageSize != 0)
+ 			size += largePageSize - (size % largePageSize);
+ 	}
+ 	else
+ 		flProtect = PAGE_READWRITE;
+ 
  #ifdef _WIN64
  	size_high = size >> 32;
  #else
***************
*** 163,169 ****
  
  		hmap = CreateFileMapping(INVALID_HANDLE_VALUE,	/* Use the pagefile */
  								 NULL,	/* Default security attrs */
! 								 PAGE_READWRITE,		/* Memory is Read/Write */
  								 size_high,		/* Size Upper 32 Bits	*/
  								 size_low,		/* Size Lower 32 bits */
  								 szShareMem);
--- 253,259 ----
  
  		hmap = CreateFileMapping(INVALID_HANDLE_VALUE,	/* Use the pagefile */
  								 NULL,	/* Default security attrs */
! 								 flProtect,
  								 size_high,		/* Size Upper 32 Bits	*/
  								 size_low,		/* Size Lower 32 bits */
  								 szShareMem);
diff -Nacr a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
*** a/src/backend/utils/misc/guc.c	2016-09-20 05:17:08.000000000 +0900
--- b/src/backend/utils/misc/guc.c	2016-09-26 11:10:56.000000000 +0900
***************
*** 3792,3798 ****
  
  	{
  		{"huge_pages", PGC_POSTMASTER, RESOURCES_MEM,
! 			gettext_noop("Use of huge pages on Linux."),
  			NULL
  		},
  		&huge_pages,
--- 3792,3798 ----
  
  	{
  		{"huge_pages", PGC_POSTMASTER, RESOURCES_MEM,
! 			gettext_noop("Use of huge pages on Linux/Windows."),
  			NULL
  		},
  		&huge_pages,
