diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 791b4daf01ea9bd4699713df0bb266ba26e96d8c..49612b0592f275cd8b3a90e48c64a333d5a75480 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -128,6 +128,56 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
   return false;
 }
 
+static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
+                                                      const IdentifierInfo &II,
+                                                      SourceLocation NameLoc) {
+  auto *RD = dyn_cast<CXXRecordDecl>(S.CurContext);
+  if (!RD || !RD->getDescribedClassTemplate())
+    return ParsedType();
+
+  // Look for type decls in dependent base classes that have known primary
+  // templates.
+  bool FoundTypeDecl = false;
+  for (const auto &Base : RD->bases()) {
+    auto *TST = Base.getType()->getAs<TemplateSpecializationType>();
+    if (!TST || !TST->isDependentType())
+      continue;
+    auto *TD = TST->getTemplateName().getAsTemplateDecl();
+    if (!TD)
+      continue;
+    auto *BasePrimaryTemplate = cast<CXXRecordDecl>(TD->getTemplatedDecl());
+    for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) {
+      if (FoundTypeDecl)
+        return ParsedType();
+      FoundTypeDecl = isa<TypeDecl>(ND);
+      if (!FoundTypeDecl)
+        return ParsedType();
+    }
+  }
+  if (!FoundTypeDecl)
+    return ParsedType();
+
+  // We found some types in dependent base classes.  Recover as if the user
+  // wrote 'typename MyClass::II' instead of 'II'.  We'll fully resolve the
+  // lookup during template instantiation.
+  S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II;
+
+  ASTContext &Context = S.Context;
+  auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false,
+                                          cast<Type>(Context.getRecordType(RD)));
+  QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II);
+
+  CXXScopeSpec SS;
+  SS.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+
+  TypeLocBuilder Builder;
+  DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+  DepTL.setNameLoc(NameLoc);
+  DepTL.setElaboratedKeywordLoc(SourceLocation());
+  DepTL.setQualifierLoc(SS.getWithLocInContext(Context));
+  return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
 /// \brief If the identifier refers to a type name within this scope,
 /// return the declaration of that type.
 ///
@@ -209,6 +259,14 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
   } else {
     // Perform unqualified name lookup.
     LookupName(Result, S);
+
+    // For unqualified lookup in a class template in MSVC mode, look into
+    // dependent base classes where the primary class template is known.
+    if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+      if (ParsedType TypeInBase =
+              recoverFromTypeInKnownDependentBase(*this, II, NameLoc))
+        return TypeInBase;
+    }
   }
 
   NamedDecl *IIDecl = nullptr;
@@ -630,6 +688,14 @@ Sema::NameClassification Sema::ClassifyName(Scope *S,
   LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
   LookupParsedName(Result, S, &SS, !CurMethod);
 
+  // For unqualified lookup in a class template in MSVC mode, look into
+  // dependent base classes where the primary class template is known.
+  if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) {
+    if (ParsedType TypeInBase =
+            recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc))
+      return TypeInBase;
+  }
+
   // Perform lookup for Objective-C instance variables (including automatically 
   // synthesized instance variables), if we're in an Objective-C method.
   // FIXME: This lookup really, really needs to be folded in to the normal
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 434039500c2a30dbde848546e9fe1275cb6caf9a..635f0b0cd00c9f8268c84e6308a49760a15a0da1 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++1y -fms-compatibility -fsyntax-only -verify %s
 
 
 template <class T>
@@ -275,3 +275,184 @@ template <typename T> struct Derived : Base<T> {
 };
 template struct Derived<int>;
 }
+
+namespace typedef_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == 4, "");
+}
+
+namespace struct_in_base {
+template <typename T> struct A { struct NameFromBase {}; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == 1, "");
+}
+
+namespace enum_in_base {
+template <typename T> struct A { enum NameFromBase { X }; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
+}
+
+namespace two_types_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B { struct NameFromBase { T m; }; };
+template <typename T> struct C : A<T>, B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+static_assert(sizeof(C<int>) == 4, "");
+}
+
+namespace type_and_decl_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B { static const T NameFromBase = 42; };
+template <typename T> struct C : A<T>, B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+}
+
+namespace classify_type_from_base {
+template <typename T> struct A { struct NameFromBase {}; };
+template <typename T> struct B : A<T> {
+  A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+}
+
+namespace classify_nontype_from_base {
+// MSVC does not do lookup of non-type declarations from dependent template base
+// classes.  The extra lookup only applies to types.
+template <typename T> struct A { void NameFromBase() {} };
+template <void (*F)()> struct B { };
+template <typename T> struct C : A<T> {
+  B<C::NameFromBase> a; // correct
+  B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
+};
+}
+
+namespace template_in_base {
+template <typename T> struct A {
+  template <typename U> struct NameFromBase { U x; };
+};
+template <typename T> struct B : A<T> {
+  // Correct form.
+  typename B::template NameFromBase<T> m;
+};
+template <typename T> struct C : A<T> {
+  // Incorrect form.
+  NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
+  //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
+};
+}
+
+namespace type_in_inner_class_in_base {
+template <typename T>
+struct A {
+  struct B { typedef T NameFromBase; };
+};
+template <typename T>
+struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace type_in_inner_template_class_in_base {
+template <typename T>
+struct A {
+  template <typename U> struct B { typedef U InnerType; };
+};
+template <typename T>
+struct C : A<T>::template B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+}
+
+namespace have_nondependent_base {
+template <typename T>
+struct A {
+  // Nothing, lookup should fail.
+};
+template <typename T>
+struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace lookup_in_function_contexts {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : A<T> {
+  // expected-warning@+1 {{lookup into dependent bases}}
+  static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
+    return {};
+  }
+
+  // FIXME: MSVC accepts all of the code below that isn't C++14 only.  Downgrade
+  // these errors to warnings.
+
+  static void memberFunc() {
+    NameFromBase x; // expected-error {{unknown type name 'NameFromBase'}}
+  }
+
+  static void funcLocalClass() {
+    struct X {
+      NameFromBase x; // expected-error {{unknown type name 'NameFromBase'}}
+    } y;
+  }
+
+  void localClassMethod() {
+    struct X {
+      void bar() {
+        NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+      }
+    } x;
+    x.bar();
+  }
+
+  static void funcLambda() {
+    auto l = []() {
+      NameFromBase x; // expected-error {{unknown type name 'NameFromBase'}}
+    };
+    l();
+  }
+
+  static constexpr int constexprFunc() {
+    NameFromBase x = {}; // expected-error {{unknown type name 'NameFromBase'}}
+    // FIXME: Suppress this diagnostic, we have an initializer.
+    // expected-error@-2 {{variables defined in a constexpr function must be initialized}}
+    return sizeof(x);
+  }
+
+  static auto autoFunc() {
+    NameFromBase x; // expected-error {{unknown type name 'NameFromBase'}}
+    return x;
+  }
+};
+
+// Force us to parse the methods.
+template struct B<int>;
+}
+
+namespace function_template_deduction {
+// Overloaded function templates.
+template <int N> int f() { return N; }
+template <typename T> int f() { return sizeof(T); }
+
+// Dependent base class with type.
+template <typename T>
+struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : A<T> {
+  // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
+  int x = f<NameFromBase>();
+};
+
+// Dependent base class with enum.
+template <typename T> struct C { enum { NameFromBase = 4 }; };
+template <typename T> struct D : C<T> {
+  // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
+  int x = f<NameFromBase>();
+};
+}