diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index e8d06f994fde663c444d3ca268a9a6995a2d4389..cc41110a0959aae2cb09f9e9dfd5af44a3655504 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -670,6 +670,12 @@ def internal_externc_isystem : JoinedOrSeparate<"-internal-externc-isystem">,
            "implicit extern \"C\" semantics; these are assumed to not be "
            "user-provided and are used to model system and standard headers' "
            "paths.">;
+def internal_nosysroot_isystem : JoinedOrSeparate<"-internal-nosysroot-isystem">,
+  MetaVarName<"<directory>">,
+  HelpText<"Add directory to the internal system include search path without "
+           "applying a sysroot to it; these are assumed to not be "
+           "user-provided and are used to model system and standard headers' "
+           "paths.">;
 def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
   HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
 def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index ab866a2407eea565497f00560ae1314980803971..c9e86334d5094b41d3f009718152c9fdfde506d1 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -2253,6 +2253,21 @@ static void addSystemIncludes(const ArgList &DriverArgs,
 
 void Windows::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                         ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdinc))
+    return;
+
+  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+    // Ignore the sysroot, we *always* look for clang headers relative to
+    // supplied path.
+    llvm::sys::Path P(getDriver().ResourceDir);
+    P.appendComponent("include");
+    CC1Args.push_back("-internal-nosysroot-isystem");
+    CC1Args.push_back(DriverArgs.MakeArgString(P.str()));
+  }
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+    return;
+
   std::string VSDir;
   std::string WindowsSDKDir;
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 1829d7de0ada3ff40eb5b8b2295343eeb126932a..1bcad24ee4d052990e4f1c0b394945950d287483 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -577,8 +577,12 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
     } else {
       if (E.IsInternal) {
         assert(E.Group == frontend::System && "Unexpected header search group");
-        Res.push_back(E.ImplicitExternC ? "-internal-externc-isystem"
-                                        : "-internal-isystem");
+        if (E.IgnoreSysRoot)
+          Res.push_back("-internal-nosysroot-isystem");
+        else if (E.ImplicitExternC)
+          Res.push_back("-internal-externc-isystem");
+        else
+          Res.push_back("-internal-isystem");
       } else {
         if (E.Group != frontend::Angled && E.Group != frontend::System)
           llvm::report_fatal_error("Invalid option set!");
@@ -1492,11 +1496,14 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
 
   // Add the internal paths from a driver that detects standard include paths.
   for (arg_iterator I = Args.filtered_begin(OPT_internal_isystem,
-                                            OPT_internal_externc_isystem),
+                                            OPT_internal_externc_isystem,
+                                            OPT_internal_nosysroot_isystem),
                     E = Args.filtered_end();
        I != E; ++I)
     Opts.AddPath((*I)->getValue(Args), frontend::System,
-                 false, false, false, /*IsInternal=*/true,
+                 false, false,
+                 (*I)->getOption().matches(OPT_internal_nosysroot_isystem),
+                 /*IsInternal=*/true,
                  (*I)->getOption().matches(OPT_internal_externc_isystem));
 }