diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 7c13907..0b465d2 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -599,6 +599,10 @@ public:
   mutable QualType AutoDeductTy;     // Deduction against 'auto'.
   mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
 
+  // Record type used to define __builtin_va_list on some targets.
+  // Built on demand.
+  mutable QualType VaListTagTy; // __va_list_tag type.
+
   ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t,
              IdentifierTable &idents, SelectorTable &sels,
              Builtin::Context &builtins,
@@ -1175,7 +1179,7 @@ public:
   QualType getObjCProtoType() const {
     return getObjCInterfaceType(getObjCProtocolDecl());
   }
-  
+
   /// \brief Retrieve the C type declaration corresponding to the predefined
   /// __builtin_va_list type.
   TypedefDecl *getBuiltinVaListDecl() const;
@@ -1185,6 +1189,10 @@ public:
     return getTypeDeclType(getBuiltinVaListDecl());
   }
 
+  /// \brief Retrieve the __va_list_tag record type used on some targets to
+  // define __builtin_va_list type.
+  QualType getVaListTagType() const;
+
   /// getCVRQualifiedType - Returns a type with additional const,
   /// volatile, or restrict qualifiers.
   QualType getCVRQualifiedType(QualType T, unsigned CVR) const {
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index fbcc5c6..47bf6d3 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -640,7 +640,9 @@ namespace clang {
       /// \brief ARC's unbridged-cast placeholder type.
       PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34,
       /// \brief The pseudo-object placeholder type.
-      PREDEF_TYPE_PSEUDO_OBJECT = 35
+      PREDEF_TYPE_PSEUDO_OBJECT = 35,
+      /// \brief __va_list_tag record type.
+      PREDEF_TYPE_VA_LIST_TAG = 36
     };
 
     /// \brief The number of predefined type IDs that are reserved for
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index f208f06..e4cca94 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -5065,7 +5065,7 @@ static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {
   return VaListTypeDecl;
 }
 
-static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
+static QualType CreatePowerABIVaListTagType(const ASTContext *Context) {
   // typedef struct __va_list_tag {
   RecordDecl *VaListTagDecl;
 
@@ -5112,37 +5112,11 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
     VaListTagDecl->addDecl(Field);
   }
   VaListTagDecl->completeDefinition();
-  QualType VaListTagType = Context->getRecordType(VaListTagDecl);
-
   // } __va_list_tag;
-  TypedefDecl *VaListTagTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__va_list_tag"),
-                          Context->getTrivialTypeSourceInfo(VaListTagType));
-  QualType VaListTagTypedefType =
-    Context->getTypedefType(VaListTagTypedefDecl);
-
-  // typedef __va_list_tag __builtin_va_list[1];
-  llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
-  QualType VaListTagArrayType
-    = Context->getConstantArrayType(VaListTagTypedefType,
-                                    Size, ArrayType::Normal, 0);
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
-  TypedefDecl *VaListTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
-
-  return VaListTypedefDecl;
+  return Context->getRecordType(VaListTagDecl);
 }
 
-static TypedefDecl *
-CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
+static QualType CreateX86_64ABIVaListTagType(const ASTContext *Context) {
   // typedef struct __va_list_tag {
   RecordDecl *VaListTagDecl;
   VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
@@ -5185,9 +5159,13 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
     VaListTagDecl->addDecl(Field);
   }
   VaListTagDecl->completeDefinition();
-  QualType VaListTagType = Context->getRecordType(VaListTagDecl);
-
   // } __va_list_tag;
+  return Context->getRecordType(VaListTagDecl);
+}
+
+static TypedefDecl *
+CreateVaListTagBasedBuiltinVaListDecl(const ASTContext *Context) {
+  QualType VaListTagType = Context->getVaListTagType();
   TypedefDecl *VaListTagTypedefDecl
     = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
                           Context->getTranslationUnitDecl(),
@@ -5201,7 +5179,7 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
   llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
   QualType VaListTagArrayType
     = Context->getConstantArrayType(VaListTagTypedefType,
-                                      Size, ArrayType::Normal,0);
+                                    Size, ArrayType::Normal, 0);
   TypeSourceInfo *TInfo
     = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
   TypedefDecl *VaListTypedefDecl
@@ -5238,9 +5216,9 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
   case TargetInfo::VoidPtrBuiltinVaList:
     return CreateVoidPtrBuiltinVaListDecl(Context);
   case TargetInfo::PowerABIBuiltinVaList:
-    return CreatePowerABIBuiltinVaListDecl(Context);
+    // fallthrough
   case TargetInfo::X86_64ABIBuiltinVaList:
-    return CreateX86_64ABIBuiltinVaListDecl(Context);
+    return CreateVaListTagBasedBuiltinVaListDecl(Context);
   case TargetInfo::PNaClABIBuiltinVaList:
     return CreatePNaClABIBuiltinVaListDecl(Context);
   }
@@ -5248,6 +5226,30 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
   llvm_unreachable("Unhandled __builtin_va_list type kind");
 }
 
+static QualType CreateVaListTagType(const ASTContext *Context,
+                                    TargetInfo::BuiltinVaListKind Kind) {
+  switch (Kind) {
+    case TargetInfo::CharPtrBuiltinVaList:
+    case TargetInfo::VoidPtrBuiltinVaList:
+    case TargetInfo::PNaClABIBuiltinVaList:
+      llvm_unreachable(
+              "__va_list_tag type not defined for this __builtin_va_list kind");
+    case TargetInfo::PowerABIBuiltinVaList:
+      return CreatePowerABIVaListTagType(Context);
+    case TargetInfo::X86_64ABIBuiltinVaList:
+      return CreateX86_64ABIVaListTagType(Context);
+  }
+
+  llvm_unreachable("Unhandled __builtin_va_list type kind");
+}
+
+QualType ASTContext::getVaListTagType() const {
+  if (VaListTagTy.isNull())
+    VaListTagTy = CreateVaListTagType(this, Target->getBuiltinVaListKind());
+
+  return VaListTagTy;
+}
+
 TypedefDecl *ASTContext::getBuiltinVaListDecl() const {
   if (!BuiltinVaListDecl)
     BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind());
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index 16db8e3..ac9dd02 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -51,6 +51,9 @@ TypeID MakeTypeID(ASTContext &Context, QualType T, IdxForTypeTy IdxForType) {
   if (T == Context.AutoRRefDeductTy)
     return TypeIdx(PREDEF_TYPE_AUTO_RREF_DEDUCT).asTypeID(FastQuals);
 
+  if (T == Context.VaListTagTy)
+    return TypeIdx(PREDEF_TYPE_VA_LIST_TAG).asTypeID(FastQuals);
+
   return IdxForType(T).asTypeID(FastQuals);
 }
 
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 8b354f3..6a23be3 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4460,7 +4460,9 @@ QualType ASTReader::GetType(TypeID ID) {
     case PREDEF_TYPE_ARC_UNBRIDGED_CAST:
       T = Context.ARCUnbridgedCastTy;
       break;
-
+    case PREDEF_TYPE_VA_LIST_TAG:
+      T = Context.getVaListTagType();
+      break;
     }
 
     assert(!T.isNull() && "Unknown predefined type");
diff --git a/test/PCH/Inputs/va_list_tag.h b/test/PCH/Inputs/va_list_tag.h
new file mode 100644
index 0000000..ceff8fc
--- /dev/null
+++ b/test/PCH/Inputs/va_list_tag.h
@@ -0,0 +1,4 @@
+
+typedef __builtin_va_list va_list;
+
+extern void vf (const char * , va_list);
diff --git a/test/PCH/va_list_tag.c b/test/PCH/va_list_tag.c
new file mode 100644
index 0000000..7e4ae6c
--- /dev/null
+++ b/test/PCH/va_list_tag.c
@@ -0,0 +1,10 @@
+// Test this without pch.
+// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include %S/Inputs/va_list_tag.h %s -verify
+
+// Test with pch.
+// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -emit-pch -x c-header -o %t %S/Inputs/va_list_tag.h
+// RUN: %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include-pch %t %s -verify
+
+void f(const char *fmt, va_list args) {
+  vf(fmt, args);
+}
