Index: include/llvm/IR/PassInstrumentation.h
===================================================================
--- include/llvm/IR/PassInstrumentation.h
+++ include/llvm/IR/PassInstrumentation.h
@@ -90,7 +90,7 @@
 /// PassInstrumentation to pass control to the registered callbacks.
 class PassInstrumentationCallbacks {
 public:
-  // Before/After Pass callbacks accept IRUnits, so they need to take them
+  // Before/After callbacks accept IRUnits, so they need to take them
   // as pointers, wrapped with llvm::Any
   using BeforePassFunc = bool(StringRef, Any);
   using AfterPassFunc = void(StringRef, Any);
@@ -112,6 +112,16 @@
     AfterPassCallbacks.push_back(C);
   }
 
+  void
+  registerBeforeAnalysisCallback(const std::function<BeforeAnalysisFunc> &C) {
+    BeforeAnalysisCallbacks.push_back(C);
+  }
+
+  void
+  registerAfterAnalysisCallback(const std::function<AfterAnalysisFunc> &C) {
+    AfterAnalysisCallbacks.push_back(C);
+  }
+
 private:
   // Instrumentation calls should not be used as a public interface.
   // Only for consumption by PassInstrumentation.
@@ -130,9 +140,17 @@
   template <typename IRUnitT>
   void runAfterPass(StringRef PassID, const IRUnitT &) const;
 
+  template <typename IRUnitT>
+  void runBeforeAnalysis(StringRef AnalysisID, const IRUnitT &) const;
+
+  template <typename IRUnitT>
+  void runAfterAnalysis(StringRef AnalysisID, const IRUnitT &) const;
+
   // instrumentation callbacks
   SmallVector<std::function<BeforePassFunc>, 4> BeforePassCallbacks;
   SmallVector<std::function<AfterPassFunc>, 4> AfterPassCallbacks;
+  SmallVector<std::function<BeforeAnalysisFunc>, 4> BeforeAnalysisCallbacks;
+  SmallVector<std::function<AfterAnalysisFunc>, 4> AfterAnalysisCallbacks;
 };
 
 /// This class provides instrumentation entry points for the Pass Manager,
@@ -163,6 +181,22 @@
       Callbacks->runAfterPass(Pass.name(), IR);
   }
 
+  /// BeforeAnalysis instrumentation point - takes \p Analysis instance
+  /// to be executed and constant reference to IR it operates on.
+  template <typename IRUnitT, typename PassT>
+  void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
+    if (Callbacks)
+      Callbacks->runBeforeAnalysis(Analysis.name(), IR);
+  }
+
+  /// AfterAnalysis instrumentation point - takes \p Analysis instance
+  /// that has just been executed and constant reference to IR it operated on.
+  template <typename IRUnitT, typename PassT>
+  void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const {
+    if (Callbacks)
+      Callbacks->runAfterAnalysis(Analysis.name(), IR);
+  }
+
   /// Handle invalidation from the pass manager when PassInstrumentation
   /// is used as the result of PassInstrumentationAnalysis.
   ///
Index: include/llvm/IR/PassManager.h
===================================================================
--- include/llvm/IR/PassManager.h
+++ include/llvm/IR/PassManager.h
@@ -927,9 +927,19 @@
       if (DebugLogging)
         dbgs() << "Running analysis: " << P.name() << " on " << IR.getName()
                << "\n";
+
+      PassInstrumentation PI;
+      if (ID != PassInstrumentationAnalysis::ID()) {
+        PI =
+            getPassInstrumentation(IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
+        PI.runBeforeAnalysis(P, IR);
+      }
+
       AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
       ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
 
+      PI.runAfterAnalysis(P, IR);
+
       // P.run may have inserted elements into AnalysisResults and invalidated
       // RI.
       RI = AnalysisResults.find({ID, &IR});
Index: lib/IR/PassInstrumentation.cpp
===================================================================
--- lib/IR/PassInstrumentation.cpp
+++ lib/IR/PassInstrumentation.cpp
@@ -35,6 +35,20 @@
     C(PassID, llvm::Any(&IR));
 }
 
+template <typename IRUnitT>
+void PassInstrumentationCallbacks::runBeforeAnalysis(StringRef AnalysisID,
+                                                     const IRUnitT &IR) const {
+  for (auto &C : BeforeAnalysisCallbacks)
+    C(AnalysisID, llvm::Any(&IR));
+}
+
+template <typename IRUnitT>
+void PassInstrumentationCallbacks::runAfterAnalysis(StringRef AnalysisID,
+                                                    const IRUnitT &IR) const {
+  for (auto &C : AfterAnalysisCallbacks)
+    C(AnalysisID, llvm::Any(&IR));
+}
+
 template bool
 PassInstrumentationCallbacks::runBeforePass(StringRef PassID,
                                             const Module &IR) const;
@@ -57,6 +71,28 @@
 template void
 PassInstrumentationCallbacks::runAfterPass(StringRef PassID,
                                            const LazyCallGraph::SCC &IR) const;
+template void
+PassInstrumentationCallbacks::runBeforeAnalysis(StringRef PassID,
+                                                const Module &IR) const;
+template void
+PassInstrumentationCallbacks::runBeforeAnalysis(StringRef PassID,
+                                                const Function &IR) const;
+template void
+PassInstrumentationCallbacks::runBeforeAnalysis(StringRef PassID,
+                                                const Loop &IR) const;
+template void PassInstrumentationCallbacks::runBeforeAnalysis(
+    StringRef PassID, const LazyCallGraph::SCC &IR) const;
+template void
+PassInstrumentationCallbacks::runAfterAnalysis(StringRef PassID,
+                                               const Module &IR) const;
+template void
+PassInstrumentationCallbacks::runAfterAnalysis(StringRef PassID,
+                                               const Function &IR) const;
+template void
+PassInstrumentationCallbacks::runAfterAnalysis(StringRef PassID,
+                                               const Loop &IR) const;
+template void PassInstrumentationCallbacks::runAfterAnalysis(
+    StringRef PassID, const LazyCallGraph::SCC &IR) const;
 
 AnalysisKey PassInstrumentationAnalysis::Key;
 
Index: test/Other/new-pm-lto-defaults.ll
===================================================================
--- test/Other/new-pm-lto-defaults.ll
+++ test/Other/new-pm-lto-defaults.ll
@@ -51,8 +51,10 @@
 ; CHECK-O1-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Function
 ; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis
 ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
+; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
 ; CHECK-O-NEXT: Running analysis: AAManager
+; CHECK-O1-NEXT: Running analysis: PassInstrumentationAnalysis
 ; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
 ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: CallGraphAnalysis
Index: test/Other/new-pm-thinlto-defaults.ll
===================================================================
--- test/Other/new-pm-thinlto-defaults.ll
+++ test/Other/new-pm-thinlto-defaults.ll
@@ -59,13 +59,14 @@
 ; CHECK-POSTLINK-O-NEXT: Running analysis: ProfileSummaryAnalysis
 ; CHECK-POSTLINK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 ; CHECK-POSTLINK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
+; CHECK-POSTLINK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}>
 ; CHECK-O-NEXT: Starting llvm::Module pass manager run.
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
 ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
 ; CHECK-PRELINK-O-NODIS-NEXT: Running analysis: InnerAnalysisManagerProxy
-; CHECK-O-NEXT: Running analysis: PassInstrumentationAnalysis
+; CHECK-PRELINK-O-NEXT: Running analysis: PassInstrumentationAnalysis
 ; CHECK-O-NEXT: Starting llvm::Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
Index: unittests/IR/PassBuilderCallbacksTest.cpp
===================================================================
--- unittests/IR/PassBuilderCallbacksTest.cpp
+++ unittests/IR/PassBuilderCallbacksTest.cpp
@@ -270,9 +270,13 @@
     // by default by PassBuilder - Verifier pass etc).
     EXPECT_CALL(*this, runBeforePass(_, _)).Times(AnyNumber());
     EXPECT_CALL(*this, runAfterPass(_, _)).Times(AnyNumber());
+    EXPECT_CALL(*this, runBeforeAnalysis(_, _)).Times(AnyNumber());
+    EXPECT_CALL(*this, runAfterAnalysis(_, _)).Times(AnyNumber());
   }
   MOCK_METHOD2(runBeforePass, bool(StringRef PassID, llvm::Any));
   MOCK_METHOD2(runAfterPass, void(StringRef PassID, llvm::Any));
+  MOCK_METHOD2(runBeforeAnalysis, void(StringRef PassID, llvm::Any));
+  MOCK_METHOD2(runAfterAnalysis, void(StringRef PassID, llvm::Any));
 };
 
 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
@@ -425,6 +429,12 @@
       PIC.registerAfterPassCallback(
           std::bind(&MockPassInstrumentationCallbacks::runAfterPass,
                     &PICallbacks, _1, _2));
+      PIC.registerBeforeAnalysisCallback(
+          std::bind(&MockPassInstrumentationCallbacks::runBeforeAnalysis,
+                    &PICallbacks, _1, _2));
+      PIC.registerAfterAnalysisCallback(
+          std::bind(&MockPassInstrumentationCallbacks::runAfterAnalysis,
+                    &PICallbacks, _1, _2));
     });
     /// Register builtin analyses and cross-register the analysis proxies
     PB.registerModuleAnalyses(AM);
@@ -464,6 +474,12 @@
     testing::InSequence InstrumentationExpectationsSequenced;
     EXPECT_CALL(PICallbacks, runBeforePass(HasNameRegex("MockPassHandle"),
                                            HasName("<string>")));
+    EXPECT_CALL(PICallbacks,
+                runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"),
+                                  HasName("<string>")));
+    EXPECT_CALL(PICallbacks,
+                runAfterAnalysis(HasNameRegex("MockAnalysisHandle"),
+                                 HasName("<string>")));
     EXPECT_CALL(PICallbacks, runAfterPass(HasNameRegex("MockPassHandle"),
                                           HasName("<string>")));
   }
@@ -484,9 +500,16 @@
   EXPECT_CALL(AnalysisHandle, run(HasName("<string>"), _)).Times(0);
   EXPECT_CALL(PassHandle, run(HasName("<string>"), _)).Times(0);
 
-  // As the pass is skipped there is no afterPass as well.
+  // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
+  // as well.
   EXPECT_CALL(PICallbacks, runAfterPass(HasNameRegex("MockPassHandle"), _))
       .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
 
   StringRef PipelineText = "test-transform";
   ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
@@ -515,6 +538,12 @@
     testing::InSequence InstrumentationExpectationsSequenced;
     EXPECT_CALL(PICallbacks,
                 runBeforePass(HasNameRegex("MockPassHandle"), HasName("foo")));
+    EXPECT_CALL(
+        PICallbacks,
+        runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo")));
+    EXPECT_CALL(
+        PICallbacks,
+        runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("foo")));
     EXPECT_CALL(PICallbacks,
                 runAfterPass(HasNameRegex("MockPassHandle"), HasName("foo")));
   }
@@ -534,9 +563,18 @@
   EXPECT_CALL(AnalysisHandle, run(HasName("foo"), _)).Times(0);
   EXPECT_CALL(PassHandle, run(HasName("foo"), _)).Times(0);
 
-  // As the pass is skipped there is no afterPass as well.
+  // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
+  // as well.
+  EXPECT_CALL(PICallbacks, runAfterPass(HasNameRegex("MockPassHandle"), _))
+      .Times(0);
   EXPECT_CALL(PICallbacks, runAfterPass(HasNameRegex("MockPassHandle"), _))
       .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
 
   StringRef PipelineText = "test-transform";
   ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
@@ -563,6 +601,12 @@
     testing::InSequence InstrumentationExpectationsSequenced;
     EXPECT_CALL(PICallbacks,
                 runBeforePass(HasNameRegex("MockPassHandle"), HasName("loop")));
+    EXPECT_CALL(
+        PICallbacks,
+        runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop")));
+    EXPECT_CALL(
+        PICallbacks,
+        runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("loop")));
     EXPECT_CALL(PICallbacks,
                 runAfterPass(HasNameRegex("MockPassHandle"), HasName("loop")));
   }
@@ -582,9 +626,16 @@
   EXPECT_CALL(AnalysisHandle, run(HasName("loop"), _, _)).Times(0);
   EXPECT_CALL(PassHandle, run(HasName("loop"), _, _, _)).Times(0);
 
-  // As the pass is skipped there is no afterPass as well.
+  // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
+  // as well.
   EXPECT_CALL(PICallbacks, runAfterPass(HasNameRegex("MockPassHandle"), _))
       .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
 
   StringRef PipelineText = "test-transform";
   ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))
@@ -612,6 +663,12 @@
     testing::InSequence InstrumentationExpectationsSequenced;
     EXPECT_CALL(PICallbacks, runBeforePass(HasNameRegex("MockPassHandle"),
                                            HasName("(foo)")));
+    EXPECT_CALL(PICallbacks,
+                runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"),
+                                  HasName("(foo)")));
+    EXPECT_CALL(
+        PICallbacks,
+        runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), HasName("(foo)")));
     EXPECT_CALL(PICallbacks,
                 runAfterPass(HasNameRegex("MockPassHandle"), HasName("(foo)")));
   }
@@ -632,9 +689,16 @@
   EXPECT_CALL(AnalysisHandle, run(HasName("(foo)"), _, _)).Times(0);
   EXPECT_CALL(PassHandle, run(HasName("(foo)"), _, _, _)).Times(0);
 
-  // As the pass is skipped there is no afterPass as well.
+  // As the pass is skipped there is no afterPass, beforeAnalysis/afterAnalysis
+  // as well.
   EXPECT_CALL(PICallbacks, runAfterPass(HasNameRegex("MockPassHandle"), _))
       .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runBeforeAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
+  EXPECT_CALL(PICallbacks,
+              runAfterAnalysis(HasNameRegex("MockAnalysisHandle"), _))
+      .Times(0);
 
   StringRef PipelineText = "test-transform";
   ASSERT_TRUE(PB.parsePassPipeline(PM, PipelineText, true))