diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h
--- a/llvm/include/llvm/Analysis/LazyCallGraph.h
+++ b/llvm/include/llvm/Analysis/LazyCallGraph.h
@@ -551,6 +551,7 @@
   class RefSCC {
     friend class LazyCallGraph;
     friend class LazyCallGraph::Node;
+    friend class CallGraphUpdater;
 
     LazyCallGraph *G;
 
diff --git a/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h b/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h
--- a/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h
+++ b/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h
@@ -30,6 +30,9 @@
   CGSCCAnalysisManager *AM = nullptr;
   CGSCCUpdateResult *UR = nullptr;
 
+  LazyCallGraph::Node &createNode(Function &Fn);
+  void addNodeToSCC(LazyCallGraph::Node &N, LazyCallGraph::SCC &SCC);
+
 public:
   CallGraphUpdater() {}
   CallGraphUpdater(CallGraph &CG) : CG(&CG) {}
@@ -49,6 +52,10 @@
   /// still needs to be re-analyzed or manually updated.
   void registerOutlinedFunction(Function &NewFn,
                                 LazyCallGraph::SCC *SCC = nullptr);
+
+  void
+  registerReferredToOutlinedFunction(Function &NewFn,
+                                     LazyCallGraph::RefSCC *RefSCC = nullptr);
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -721,7 +721,7 @@
   // Set the edge kind.
   SourceN->setEdgeKind(TargetN, Edge::Ref);
 
-  // Otherwise we are removing a call edge from a single SCC. This may break
+  // Otherwise, we are removing a call edge from a single SCC. This may break
   // the cycle. In order to compute the new set of SCCs, we need to do a small
   // DFS over the nodes within the SCC to form any sub-cycles that remain as
   // distinct SCCs and compute a postorder over the resulting SCCs.
diff --git a/llvm/lib/Transforms/Utils/CallGraphUpdater.cpp b/llvm/lib/Transforms/Utils/CallGraphUpdater.cpp
--- a/llvm/lib/Transforms/Utils/CallGraphUpdater.cpp
+++ b/llvm/lib/Transforms/Utils/CallGraphUpdater.cpp
@@ -16,6 +16,23 @@
 
 using namespace llvm;
 
+LazyCallGraph::Node &CallGraphUpdater::createNode(Function &Fn) {
+  assert(LCG);
+  assert(!LCG->lookup(Fn) && "node already exists");
+
+  LazyCallGraph::Node &CGNode = LCG->get(Fn);
+  LCG->NodeMap[&Fn] = &CGNode;
+  CGNode.DFSNumber = CGNode.LowLink = -1;
+  CGNode.populate();
+  return CGNode;
+}
+
+void CallGraphUpdater::addNodeToSCC(LazyCallGraph::Node &N,
+                                    LazyCallGraph::SCC &SCC) {
+  SCC.Nodes.push_back(&N);
+  LCG->SCCMap[&N] = &SCC;
+}
+
 void CallGraphUpdater::reanalyzeFunction(Function &Fn) {
   if (CG) {
     CallGraphNode *OldCGN = (*CG)[&Fn];
@@ -34,12 +51,27 @@
   if (CG) {
     CG->addToCallGraph(&NewFn);
   } else if (LCG) {
-    LazyCallGraph::Node &CGNode = LCG->get(NewFn);
-    CGNode.DFSNumber = CGNode.LowLink = -1;
-    CGNode.populate();
-    SCC->Nodes.push_back(&CGNode);
-    LCG->SCCMap[&CGNode] = SCC;
-    LCG->NodeMap[&NewFn] = &CGNode;
+    LazyCallGraph::Node &CGNode = createNode(NewFn);
+    addNodeToSCC(CGNode, *SCC);
+  }
+}
+
+void CallGraphUpdater::registerReferredToOutlinedFunction(
+    Function &NewFn, LazyCallGraph::RefSCC *RefSCC) {
+  if (CG) {
+    llvm_unreachable("registering referred to functions is not supported "
+                     "with CallGraph");
+  } else if (LCG) {
+    assert(RefSCC && "when using LazyCallGraph RefSCC must not be null");
+
+    LazyCallGraph::Node &CGNode = createNode(NewFn);
+    SmallVector<LazyCallGraph::Node *, 1> Nodes;
+    Nodes.push_back(&CGNode);
+    auto *SCC = LCG->createSCC(*RefSCC, Nodes);
+    addNodeToSCC(CGNode, *SCC);
+
+    RefSCC->SCCIndices[SCC] = RefSCC->SCCIndices.size();
+    RefSCC->SCCs.push_back(SCC);
   }
 }
 
diff --git a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
--- a/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
+++ b/llvm/unittests/Analysis/CGSCCPassManagerTest.cpp
@@ -1560,5 +1560,54 @@
   MPM.run(*M, MAM);
 }
 
+TEST_F(CGSCCPassManagerTest, TestInsertionOfNewRefSCC) {
+  std::unique_ptr<Module> M = parseIR("define void @f() {\n"
+                                      "entry:\n"
+                                      "  call void @f()\n"
+                                      "  ret void\n"
+                                      "}\n");
+
+  CGSCCPassManager CGPM(/*DebugLogging*/ true);
+  CGPM.addPass(LambdaSCCPassNoPreserve(
+      [&](LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG,
+          CGSCCUpdateResult &UR) {
+        CallGraphUpdater CGUpdater(CG, AM, UR);
+        for (auto &N : C) {
+          auto &F = N.getFunction();
+          if (F.getName() != "f")
+            continue;
+          auto *Call = dyn_cast<CallInst>(F.begin()->begin());
+          if (!Call || Call->getCalledFunction()->getName() != "f")
+            continue;
+
+          // Create a new function 'g' and use the CallGraphUpdater to insert
+          // a RefSCC, SCC, and node for 'g' into the call graph. As a result
+          // the call graph is composed of two RefSCCs, [(f)] and [(g)].
+          auto *G = Function::Create(F.getFunctionType(), F.getLinkage(),
+                                     F.getAddressSpace(), "g", F.getParent());
+          BasicBlock::Create(F.getParent()->getContext(), "entry", G);
+          CGUpdater.registerReferredToOutlinedFunction(*G, &C.getOuterRefSCC());
+
+          // "Demote" the 'f -> f' call egde to a ref edge.
+          // 1. Erase the call edge from 'f' to 'f'.
+          Call->eraseFromParent();
+          // 2. Insert a ref edge from 'f' to 'f'.
+          (void)CastInst::CreatePointerCast(&F,
+                                            Type::getInt8PtrTy(F.getContext()),
+                                            "f.ref", &*F.begin()->begin());
+
+          ASSERT_NO_FATAL_FAILURE(
+              updateCGAndAnalysisManagerForCGSCCPass(CG, C, N, AM, UR))
+              << "Updating the call graph with a demoted, self-referential "
+                 "call edge 'f -> f', and a newly inserted ref edge 'f -> g', "
+                 "caused a fatal failure";
+        }
+      }));
+
+  ModulePassManager MPM(/*DebugLogging*/ true);
+  MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
+  MPM.run(*M, MAM);
+}
+
 #endif
 } // namespace