diff --git a/.gitignore b/.gitignore
index 4f129c4581ba8f..b3f74791c07383 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,7 @@ ipch/
 *.VC.opendb
 .vs/
 .vscode/
+/Set_VS*.bat
 
 /config.mk
 /config.gypi
diff --git a/BUILDING.md b/BUILDING.md
index a28759e1c7cc1e..3ca51bec38ab2c 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -111,6 +111,9 @@ Prerequisites:
   * [Visual Studio 2015 Update 3](https://www.visualstudio.com/), all editions
     including the Community edition (remember to select
     "Common Tools for Visual C++ 2015" feature during installation).
+  * [Visual Studio 2017](https://www.visualstudio.com/), all editions. The
+    required components are "VC++ 2017 v141 toolset", "Visual Studio C++ core
+    features" and one of the "Windows 10 SDK".
 * Basic Unix tools required for some tests,
   [Git for Windows](http://git-scm.com/download/win) includes Git Bash
   and tools which can be included in the global `PATH`.
diff --git a/tools/Find-VS2017.cs b/tools/Find-VS2017.cs
new file mode 100644
index 00000000000000..54a812ee160316
--- /dev/null
+++ b/tools/Find-VS2017.cs
@@ -0,0 +1,270 @@
+// Copyright 2017 - Refael Ackermann
+// Distributed under MIT style license
+// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
+
+// Usage:
+// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}"
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+
+namespace VisualStudioConfiguration
+{
+    [Flags]
+    public enum InstanceState : uint
+    {
+        None = 0,
+        Local = 1,
+        Registered = 2,
+        NoRebootRequired = 4,
+        NoErrors = 8,
+        Complete = 4294967295,
+    }
+
+    [Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface IEnumSetupInstances
+    {
+
+        void Next([MarshalAs(UnmanagedType.U4), In] int celt,
+            [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
+            [MarshalAs(UnmanagedType.U4)] out int pceltFetched);
+
+        void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
+
+        void Reset();
+
+        [return: MarshalAs(UnmanagedType.Interface)]
+        IEnumSetupInstances Clone();
+    }
+
+    [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface ISetupConfiguration
+    {
+    }
+
+    [Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface ISetupConfiguration2 : ISetupConfiguration
+    {
+
+        [return: MarshalAs(UnmanagedType.Interface)]
+        IEnumSetupInstances EnumInstances();
+
+        [return: MarshalAs(UnmanagedType.Interface)]
+        ISetupInstance GetInstanceForCurrentProcess();
+
+        [return: MarshalAs(UnmanagedType.Interface)]
+        ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
+
+        [return: MarshalAs(UnmanagedType.Interface)]
+        IEnumSetupInstances EnumAllInstances();
+    }
+
+    [Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface ISetupInstance
+    {
+    }
+
+    [Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface ISetupInstance2 : ISetupInstance
+    {
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetInstanceId();
+
+        [return: MarshalAs(UnmanagedType.Struct)]
+        System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetInstallationName();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetInstallationPath();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetInstallationVersion();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
+
+        [return: MarshalAs(UnmanagedType.U4)]
+        InstanceState GetState();
+
+        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
+        ISetupPackageReference[] GetPackages();
+
+        ISetupPackageReference GetProduct();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetProductPath();
+
+        [return: MarshalAs(UnmanagedType.VariantBool)]
+        bool IsLaunchable();
+
+        [return: MarshalAs(UnmanagedType.VariantBool)]
+        bool IsComplete();
+
+        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
+        ISetupPropertyStore GetProperties();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetEnginePath();
+    }
+
+    [Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface ISetupPackageReference
+    {
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetId();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetVersion();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetChip();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetLanguage();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetBranch();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetType();
+
+        [return: MarshalAs(UnmanagedType.BStr)]
+        string GetUniqueId();
+
+        [return: MarshalAs(UnmanagedType.VariantBool)]
+        bool GetIsExtension();
+    }
+
+    [Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
+    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+    [ComImport]
+    public interface ISetupPropertyStore
+    {
+
+        [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
+        string[] GetNames();
+
+        object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
+    }
+
+    [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
+    [CoClass(typeof(SetupConfigurationClass))]
+    [ComImport]
+    public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
+    {
+    }
+
+    [Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
+    [ClassInterface(ClassInterfaceType.None)]
+    [ComImport]
+    public class SetupConfigurationClass
+    {
+    }
+
+    public static class Main
+    {
+        public static void Query()
+        {
+            ISetupConfiguration query = new SetupConfiguration();
+            ISetupConfiguration2 query2 = (ISetupConfiguration2)query;
+            IEnumSetupInstances e = query2.EnumAllInstances();
+
+            int pceltFetched;
+            ISetupInstance2[] rgelt = new ISetupInstance2[1];
+            while (true)
+            {
+                e.Next(1, rgelt, out pceltFetched);
+                if (pceltFetched <= 0)
+                {
+                    Console.WriteLine("No usable installation of VS2017 found");
+                    return;
+                }
+                if (CheckInstance(rgelt[0]))
+                    return;
+            }
+        }
+
+        private static bool CheckInstance(ISetupInstance2 setupInstance2)
+        {
+            // Visual Studio Community 2017 component directory:
+            // https://www.visualstudio.com/en-us/productinfo/vs2017-install-product-Community.workloads
+
+            string path = setupInstance2.GetInstallationPath();
+            Console.WriteLine(String.Format("Found VS2017 installation at: {0}", path));
+
+            bool hasMSBuild = false;
+            bool hasVCTools = false;
+            uint Win10SDKVer = 0;
+            bool hasWin8SDK = false;
+
+            foreach (ISetupPackageReference package in setupInstance2.GetPackages())
+            {
+                const string Win10SDKPrefix = "Microsoft.VisualStudio.Component.Windows10SDK.";
+
+                string id = package.GetId();
+                if (id == "Microsoft.VisualStudio.VC.MSBuild.Base")
+                    hasMSBuild = true;
+                else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64")
+                    hasVCTools = true;
+                else if (id.StartsWith(Win10SDKPrefix))
+                    Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(id.Substring(Win10SDKPrefix.Length)));
+                else if (id == "Microsoft.VisualStudio.Component.Windows81SDK")
+                    hasWin8SDK = true;
+                else
+                    continue;
+
+                Console.WriteLine(String.Format("  - Found {0}", id));
+            }
+
+            if (!hasMSBuild)
+                Console.WriteLine("  - Missing Visual Studio C++ core features (Microsoft.VisualStudio.VC.MSBuild.Base)");
+            if (!hasVCTools)
+                Console.WriteLine("  - Missing VC++ 2017 v141 toolset (x86,x64) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64)");
+            if ((Win10SDKVer == 0) && (!hasWin8SDK))
+                Console.WriteLine("  - Missing a Windows SDK (Microsoft.VisualStudio.Component.Windows10SDK.* or Microsoft.VisualStudio.Component.Windows81SDK)");
+
+            if (hasMSBuild && hasVCTools)
+            {
+                string setPath = String.Format("set \"VS2017_INSTALL={0}\"", path);
+                if (Win10SDKVer > 0)
+                {
+                    Console.WriteLine("  - Using this installation with Windows 10 SDK");
+                    string[] lines = { setPath, String.Format("set \"VS2017_SDK=10.0.{0}.0\"", Win10SDKVer) };
+                    System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines);
+                    return true;
+                }
+                else if (hasWin8SDK)
+                {
+                    Console.WriteLine("  - Using this installation with Windows 8.1 SDK");
+                    string[] lines = { setPath, "set \"VS2017_SDK=8.1\"" };
+                    System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines);
+                    return true;
+                }
+            }
+
+            Console.WriteLine("  - Some required components are missing, not using this installation");
+            return false;
+        }
+    }
+}
diff --git a/tools/gyp/pylib/gyp/MSVSVersion.py b/tools/gyp/pylib/gyp/MSVSVersion.py
index d9bfa684fa30c2..1ed016502a7531 100644
--- a/tools/gyp/pylib/gyp/MSVSVersion.py
+++ b/tools/gyp/pylib/gyp/MSVSVersion.py
@@ -84,6 +84,10 @@ def SetupScript(self, target_arch):
       # vcvars32, which it can only find if VS??COMNTOOLS is set, which it
       # isn't always.
       if target_arch == 'x86':
+        if self.short_name == '2017':
+          return [os.path.normpath(
+            os.path.join(self.path, 'Common7/Tools/VsDevCmd.bat')), '/no_logo',
+            '/arch=x86']
         if self.short_name >= '2013' and self.short_name[-1] != 'e' and (
             os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or
             os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'):
@@ -96,6 +100,10 @@ def SetupScript(self, target_arch):
           os.path.join(self.path, 'Common7/Tools/vsvars32.bat'))]
       else:
         assert target_arch == 'x64'
+        if self.short_name == '2017':
+          return [os.path.normpath(
+            os.path.join(self.path, 'Common7/Tools/VsDevCmd.bat')), '/no_logo',
+            '/arch=x64']
         arg = 'x86_amd64'
         # Use the 64-on-64 compiler if we're not using an express
         # edition and we're running on a 64bit OS.
@@ -226,6 +234,15 @@ def _CreateVersion(name, path, sdk_based=False):
   if path:
     path = os.path.normpath(path)
   versions = {
+      '2017': VisualStudioVersion('2017',
+                                  'Visual Studio 2017',
+                                  solution_version='12.00',
+                                  project_version='14.0',
+                                  flat_sln=False,
+                                  uses_vcxproj=True,
+                                  path=path,
+                                  sdk_based=sdk_based,
+                                  default_toolset='v141'),
       '2015': VisualStudioVersion('2015',
                                   'Visual Studio 2015',
                                   solution_version='12.00',
@@ -346,6 +363,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
       2012(e) - Visual Studio 2012 (11)
       2013(e) - Visual Studio 2013 (12)
       2015    - Visual Studio 2015 (14)
+      2017    - Visual Studio 2017 (15)
     Where (e) is e for express editions of MSVS and blank otherwise.
   """
   version_to_year = {
@@ -355,6 +373,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
       '11.0': '2012',
       '12.0': '2013',
       '14.0': '2015',
+      '15.0': '2017',
   }
   versions = []
   for version in versions_to_check:
@@ -395,6 +414,17 @@ def _DetectVisualStudioVersions(versions_to_check, force_express):
         versions.append(_CreateVersion(version_to_year[version] + 'e',
             os.path.join(path, '..'), sdk_based=True))
 
+    if version == '15.0':
+      # The VC++ 2017 install location needs to be located using COM instead of
+      # the registry. For details see:
+      # https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
+      # For now we use a hardcoded default with an environment variable
+      # override.
+      path = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional'
+      path = os.environ.get('vs2017_install', path)
+      if os.path.exists(path):
+        versions.append(_CreateVersion('2017', path))
+
   return versions
 
 
@@ -410,7 +440,7 @@ def SelectVisualStudioVersion(version='auto', allow_fallback=True):
   if version == 'auto':
     version = os.environ.get('GYP_MSVS_VERSION', 'auto')
   version_map = {
-    'auto': ('14.0', '12.0', '10.0', '9.0', '8.0', '11.0'),
+    'auto': ('15.0', '14.0', '12.0', '10.0', '9.0', '8.0', '11.0'),
     '2005': ('8.0',),
     '2005e': ('8.0',),
     '2008': ('9.0',),
@@ -422,6 +452,7 @@ def SelectVisualStudioVersion(version='auto', allow_fallback=True):
     '2013': ('12.0',),
     '2013e': ('12.0',),
     '2015': ('14.0',),
+    '2017': ('15.0',),
   }
   override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH')
   if override_path:
diff --git a/tools/gyp/pylib/gyp/generator/msvs.py b/tools/gyp/pylib/gyp/generator/msvs.py
index 44cc1304a2e8ed..7dd24f68403652 100644
--- a/tools/gyp/pylib/gyp/generator/msvs.py
+++ b/tools/gyp/pylib/gyp/generator/msvs.py
@@ -2622,7 +2622,7 @@ def _GetMSBuildProjectConfigurations(configurations):
   return [group]
 
 
-def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name):
+def _GetMSBuildGlobalProperties(spec, version, guid, gyp_file_name):
   namespace = os.path.splitext(gyp_file_name)[0]
   properties = [
       ['PropertyGroup', {'Label': 'Globals'},
@@ -2662,6 +2662,15 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name):
     else:
       properties[0].append(['ApplicationType', 'Windows Store'])
 
+  msvs_windows_sdk_version = None
+  if msvs_windows_sdk_version == None and version.ShortName() == '2017':
+    vs2017_sdk = '10.0.14393.0'
+    vs2017_sdk = os.environ.get('vs2017_sdk', vs2017_sdk)
+    if vs2017_sdk:
+      msvs_windows_sdk_version = vs2017_sdk
+  if msvs_windows_sdk_version:
+    properties[0].append(['WindowsTargetPlatformVersion',
+                          str(msvs_windows_sdk_version)])
   return properties
 
 def _GetMSBuildConfigurationDetails(spec, build_file):
@@ -3295,7 +3304,8 @@ def _GenerateMSBuildProject(project, options, version, generator_flags):
       }]
 
   content += _GetMSBuildProjectConfigurations(configurations)
-  content += _GetMSBuildGlobalProperties(spec, project.guid, project_file_name)
+  content += _GetMSBuildGlobalProperties(spec, version, project.guid,
+                                         project_file_name)
   content += import_default_section
   content += _GetMSBuildConfigurationDetails(spec, project.build_file)
   if spec.get('msvs_enable_winphone'):
diff --git a/vcbuild.bat b/vcbuild.bat
index f07c50b0fbfc91..4cfdad57cf18f3 100644
--- a/vcbuild.bat
+++ b/vcbuild.bat
@@ -50,6 +50,7 @@ if /i "%1"=="ia32"          set target_arch=x86&goto arg-ok
 if /i "%1"=="x86"           set target_arch=x86&goto arg-ok
 if /i "%1"=="x64"           set target_arch=x64&goto arg-ok
 if /i "%1"=="vc2015"        set target_env=vc2015&goto arg-ok
+if /i "%1"=="vc2017"        set target_env=vc2017&goto arg-ok
 if /i "%1"=="noprojgen"     set noprojgen=1&goto arg-ok
 if /i "%1"=="nobuild"       set nobuild=1&goto arg-ok
 if /i "%1"=="nosign"        set "sign="&echo Note: vcbuild no longer signs by default. "nosign" is redundant.&goto arg-ok
@@ -137,7 +138,36 @@ if defined noprojgen if defined nobuild if not defined sign if not defined msi g
 
 @rem Set environment for msbuild
 
+@rem Look for Visual Studio 2017
+:vc-set-2017
+if defined target_env if "%target_env%" NEQ "vc2017" goto vc-set-2015
+echo Looking for Visual Studio 2017
+del /F /Q Set_VS2017.bat > nul 2> nul
+"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Unrestricted -Command ^
+  "&{Add-Type -Path .\tools\Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" 2> nul
+if not exist Set_VS2017.bat goto vc-set-2015
+call Set_VS2017.bat
+if not defined VS2017_INSTALL goto vc-set-2015
+if not defined VS2017_SDK goto vc-set-2015
+echo Found Visual Studio 2017
+if defined msi (
+  echo Cannot build the MSI with Visual Studio 2017 - it is not yet supported by WiX
+  goto vc-set-2015
+)
+if "%target_arch%"=="x86" set "VSARCH=-arch=x86"
+if "%target_arch%"=="x64" set "VSARCH=-arch=amd64"
+if "%VCVARS_VER%" NEQ "150" (
+  call "%VS2017_INSTALL%\Common7\Tools\VsDevCmd.bat" %VSARCH% /no_logo
+  set VCVARS_VER=150
+)
+if not defined VCINSTALLDIR goto vc-set-2015
+set GYP_MSVS_VERSION=2017
+set PLATFORM_TOOLSET=v141
+goto msbuild-found
+
 @rem Look for Visual Studio 2015
+:vc-set-2015
+if defined target_env if "%target_env%" NEQ "vc2015" goto msbuild-not-found
 echo Looking for Visual Studio 2015
 if not defined VS140COMNTOOLS goto msbuild-not-found
 if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto msbuild-not-found
@@ -372,7 +402,7 @@ echo Failed to create vc project files.
 goto exit
 
 :help
-echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-inspector/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/without-intl] [nobuild] [sign] [x86/x64] [vc2015] [download-all] [enable-vtune]
+echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-inspector/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/without-intl] [nobuild] [sign] [x86/x64] [vc2015/vc2017] [download-all] [enable-vtune]
 echo Examples:
 echo   vcbuild.bat                : builds release build
 echo   vcbuild.bat debug          : builds debug build