diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 6589f84c93138422b7e6c3549c3f77559ff4ad93..0dd9477e922d114a7096838ecc87942b1e4f49a4 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -131,6 +131,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
   /// \brief Whether we have already loaded macros from the external source.
   mutable bool ReadMacrosFromExternalSource : 1;
 
+  /// \brief True if pragmas are enabled.
+  bool PragmasEnabled : 1;
+
   /// \brief True if we are pre-expanding macro arguments.
   bool InMacroArgPreExpansion;
 
@@ -416,6 +419,9 @@ public:
 
   bool getCommentRetentionState() const { return KeepComments; }
 
+  void setPragmasEnabled(bool Enabled) { PragmasEnabled = Enabled; }
+  bool getPragmasEnabled() const { return PragmasEnabled; }
+
   void SetSuppressIncludeNotFoundError(bool Suppress) {
     SuppressIncludeNotFoundError = Suppress;
   }
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index e2a192b01f287c38eed37aff7fe8942724335595..d678ce5d7fbeaa3f67982c3786d0a32af37c3ffd 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -103,6 +103,9 @@ void PragmaNamespace::HandlePragma(Preprocessor &PP,
 /// HandlePragmaDirective - The "#pragma" directive has been parsed.  Lex the
 /// rest of the pragma, passing it to the registered pragma handlers.
 void Preprocessor::HandlePragmaDirective(unsigned Introducer) {
+  if (!PragmasEnabled)
+    return;
+
   ++NumPragma;
 
   // Invoke the first level of pragma handlers which reads the namespace id.
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 4be59c65f77a515f180b1481b1444936f4873a62..b420c6cd1d289db0bcc4da98466a5fe9f48de356 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -90,7 +90,8 @@ Preprocessor::Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
   InMacroArgs = false;
   InMacroArgPreExpansion = false;
   NumCachedTokenLexers = 0;
-  
+  PragmasEnabled = true;
+
   CachedLexPos = 0;
   
   // We haven't read anything from the external source.
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index dc39dde7ff1f9b7ab33e54ac6fde27fcd23cb012..e2da26fc80c5fd96ab71c841a56d6360a29baa8a 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -495,6 +495,11 @@ void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
   // Inform the preprocessor that we don't want comments.
   TmpPP.SetCommentRetentionState(false, false);
 
+  // We don't want pragmas either. Although we filtered out #pragma, removing
+  // _Pragma and __pragma is much harder.
+  bool PragmasPreviouslyEnabled = TmpPP.getPragmasEnabled();
+  TmpPP.setPragmasEnabled(false);
+
   // Enter the tokens we just lexed.  This will cause them to be macro expanded
   // but won't enter sub-files (because we removed #'s).
   TmpPP.EnterTokenStream(&TokenStream[0], TokenStream.size(), false, false);
@@ -571,6 +576,7 @@ void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
                    "<span class='macro'>", Expansion.c_str());
   }
 
-  // Restore diagnostics object back to its own thing.
+  // Restore the preprocessor's old state.
   TmpPP.setDiagnostics(*OldDiags);
+  TmpPP.setPragmasEnabled(PragmasPreviouslyEnabled);
 }
diff --git a/test/Misc/emit-html.c b/test/Misc/emit-html.c
index 48c8b61b38de2aaa2e5c0089db77fb4a93476f2b..ec07a60a60668361bfcfde00fd7f177433a17208 100644
--- a/test/Misc/emit-html.c
+++ b/test/Misc/emit-html.c
@@ -16,3 +16,11 @@ int main(int argc, char **argv) {
   FOR_ALL_FILES(f) { }
 #endif
 
+// <rdar://problem/11625964>
+// -emit-html filters out # directives, but not _Pragma (or MS __pragma)
+// Diagnostic push/pop is stateful, so re-lexing a file can cause problems
+// if these pragmas are interpreted normally.
+_Pragma("clang diagnostic push")
+_Pragma("clang diagnostic ignored \"-Wformat-extra-args\"")
+_Pragma("clang diagnostic pop")
+