diff --git chrome/app/chrome_main_delegate.cc chrome/app/chrome_main_delegate.cc
index fb5093709a104..2a69318c3e5e2 100644
--- chrome/app/chrome_main_delegate.cc
+++ chrome/app/chrome_main_delegate.cc
@@ -39,6 +39,7 @@
 #include "base/trace_event/trace_event_impl.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/buildflags.h"
 #include "chrome/browser/chrome_content_browser_client.h"
 #include "chrome/browser/chrome_resource_bundle_helper.h"
@@ -502,6 +503,8 @@ struct MainFunction {
 
 // Initializes the user data dir. Must be called before InitializeLocalState().
 void InitializeUserDataDir(base::CommandLine* command_line) {
+  if (cef::IsChromeRuntimeEnabled())
+    return;
 #if BUILDFLAG(IS_WIN)
   // Reach out to chrome_elf for the truth on the user data directory.
   // Note that in tests, this links to chrome_elf_test_stubs.
@@ -651,6 +654,10 @@ ChromeMainDelegate::~ChromeMainDelegate() {
 ChromeMainDelegate::~ChromeMainDelegate() = default;
 #endif  // !BUILDFLAG(IS_ANDROID)
 
+void ChromeMainDelegate::CleanupOnUIThread() {
+  memory_system_.reset();
+}
+
 absl::optional<int> ChromeMainDelegate::PostEarlyInitialization(
     InvokedIn invoked_in) {
   DCHECK(base::ThreadPoolInstance::Get());
@@ -867,7 +874,8 @@ absl::optional<int> ChromeMainDelegate::PostEarlyInitialization(
 
   if (base::FeatureList::IsEnabled(
           features::kWriteBasicSystemProfileToPersistentHistogramsFile)) {
-    bool record = true;
+    // Avoid CEF crash with multi-threaded-message-loop.
+    bool record = !cef::IsChromeRuntimeEnabled();
 #if BUILDFLAG(IS_ANDROID)
     record =
         base::FeatureList::IsEnabled(chrome::android::kUmaBackgroundSessions);
@@ -1294,6 +1302,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
   std::string process_type =
       command_line.GetSwitchValueASCII(switches::kProcessType);
 
+  if (!cef::IsChromeRuntimeEnabled()) {
   crash_reporter::InitializeCrashKeys();
 
 #if BUILDFLAG(IS_POSIX)
@@ -1304,6 +1313,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
   InitMacCrashReporter(command_line, process_type);
   SetUpInstallerPreferences(command_line);
 #endif
+  }  // !cef::IsChromeRuntimeEnabled()
 
 #if BUILDFLAG(IS_WIN)
   child_process_logging::Init();
@@ -1498,6 +1508,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
     CHECK(!loaded_locale.empty()) << "Locale could not be found for " << locale;
   }
 
+  if (!cef::IsChromeRuntimeEnabled()) {
 #if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC)
   // Zygote needs to call InitCrashReporter() in RunZygote().
   if (process_type != switches::kZygoteProcess) {
@@ -1541,6 +1552,7 @@ void ChromeMainDelegate::PreSandboxStartup() {
   // After all the platform Breakpads have been initialized, store the command
   // line for crash reporting.
   crash_keys::SetCrashKeysFromCommandLine(command_line);
+  }  // !cef::IsChromeRuntimeEnabled()
 
 #if BUILDFLAG(ENABLE_PDF)
   MaybePatchGdiGetFontData();
@@ -1664,6 +1676,7 @@ void ChromeMainDelegate::ZygoteForked() {
     SetUpProfilingShutdownHandler();
   }
 
+  if (!cef::IsChromeRuntimeEnabled()) {
   // Needs to be called after we have chrome::DIR_USER_DATA.  BrowserMain sets
   // this up for the browser process in a different manner.
   const base::CommandLine* command_line =
@@ -1686,6 +1699,7 @@ void ChromeMainDelegate::ZygoteForked() {
 
   // Reset the command line for the newly spawned process.
   crash_keys::SetCrashKeysFromCommandLine(*command_line);
+  }  // !cef::IsChromeRuntimeEnabled()
 }
 
 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
@@ -1783,6 +1797,7 @@ void ChromeMainDelegate::InitializeMemorySystem() {
                               channel == version_info::Channel::DEV);
   const bool gwp_asan_boost_sampling = is_canary_dev || is_browser_process;
 
+  memory_system_ = std::make_unique<memory_system::MemorySystem>();
   memory_system::Initializer()
       .SetGwpAsanParameters(gwp_asan_boost_sampling, process_type)
       .SetProfilingClientParameters(channel,
@@ -1791,5 +1806,5 @@ void ChromeMainDelegate::InitializeMemorySystem() {
                                    PoissonAllocationSamplerInclusion::kEnforce,
                                memory_system::DispatcherParameters::
                                    AllocationTraceRecorderInclusion::kDynamic)
-      .Initialize(memory_system_);
+      .Initialize(*memory_system_);
 }
diff --git chrome/app/chrome_main_delegate.h chrome/app/chrome_main_delegate.h
index dad9f981d2e01..29baaf84465a0 100644
--- chrome/app/chrome_main_delegate.h
+++ chrome/app/chrome_main_delegate.h
@@ -49,6 +49,8 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
 
   ~ChromeMainDelegate() override;
 
+  virtual void CleanupOnUIThread();
+
  protected:
   // content::ContentMainDelegate:
   absl::optional<int> BasicStartupComplete() override;
@@ -98,7 +100,7 @@ class ChromeMainDelegate : public content::ContentMainDelegate {
 
   ChromeContentClient chrome_content_client_;
 
-  memory_system::MemorySystem memory_system_;
+  std::unique_ptr<memory_system::MemorySystem> memory_system_;
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   std::unique_ptr<chromeos::LacrosService> lacros_service_;
diff --git chrome/browser/chrome_browser_main.cc chrome/browser/chrome_browser_main.cc
index b759be27d35ab..75d3c03b748a2 100644
--- chrome/browser/chrome_browser_main.cc
+++ chrome/browser/chrome_browser_main.cc
@@ -51,6 +51,7 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "cc/base/switches.h"
+#include "cef/libcef/features/runtime.h"
 #include "chrome/browser/about_flags.h"
 #include "chrome/browser/active_use_util.h"
 #include "chrome/browser/after_startup_task_utils.h"
@@ -1499,7 +1500,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   }
 #endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
 
-#if BUILDFLAG(ENABLE_PROCESS_SINGLETON)
+#if BUILDFLAG(ENABLE_PROCESS_SINGLETON) && !BUILDFLAG(ENABLE_CEF)
   // Handle special early return paths (which couldn't be processed even earlier
   // as they require the process singleton to be held) first.
 
@@ -1546,7 +1547,7 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
     return content::RESULT_CODE_NORMAL_EXIT;
 #endif  // BUILDFLAG(IS_WIN)
   }
-#endif  // BUILDFLAG(ENABLE_PROCESS_SINGLETON)
+#endif  // BUILDFLAG(ENABLE_PROCESS_SINGLETON) && !BUILDFLAG(ENABLE_CEF)
 
 #if BUILDFLAG(IS_WIN)
   // Check if there is any machine level Chrome installed on the current
@@ -1601,12 +1602,14 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
         browser_process_->local_state());
   }
 
+#if !BUILDFLAG(ENABLE_CEF)
   // Needs to be done before PostProfileInit, since login manager on CrOS is
   // called inside PostProfileInit.
   content::WebUIControllerFactory::RegisterFactory(
       ChromeWebUIControllerFactory::GetInstance());
   RegisterChromeWebUIConfigs();
   RegisterChromeUntrustedWebUIConfigs();
+#endif
 
 #if BUILDFLAG(IS_ANDROID)
   page_info::SetPageInfoClient(new ChromePageInfoClient());
@@ -1755,6 +1758,10 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
   }
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
+  // Bypass StartupBrowserCreator and RunLoop creation with CEF.
+  // CEF with the Chrome runtime will create and manage its own RunLoop.
+#if !BUILDFLAG(ENABLE_CEF)
+
   // This step is costly and is already measured in
   // Startup.StartupBrowserCreator_Start.
   // See the comment above for an explanation of |process_command_line|.
@@ -1793,11 +1800,14 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
 
     // Create the RunLoop for MainMessageLoopRun() to use and transfer
     // ownership of the browser's lifetime to the BrowserProcess.
+    // CEF with the Chrome runtime will create and manage its own RunLoop.
     DCHECK(!GetMainRunLoopInstance());
     GetMainRunLoopInstance() = std::make_unique<base::RunLoop>();
     browser_process_->SetQuitClosure(
         GetMainRunLoopInstance()->QuitWhenIdleClosure());
   }
+#endif  // !BUILDFLAG(ENABLE_CEF)
+
   browser_creator_.reset();
 #endif  // !BUILDFLAG(IS_ANDROID)
 
diff --git chrome/browser/chrome_browser_main_mac.mm chrome/browser/chrome_browser_main_mac.mm
index d495e1a903fd8..31cf6632e831c 100644
--- chrome/browser/chrome_browser_main_mac.mm
+++ chrome/browser/chrome_browser_main_mac.mm
@@ -17,6 +17,7 @@
 #include "base/path_service.h"
 #include "base/strings/sys_string_conversions.h"
 #include "build/branding_buildflags.h"
+#include "cef/libcef/features/features.h"
 #import "chrome/browser/app_controller_mac.h"
 #include "chrome/browser/apps/app_shim/app_shim_listener.h"
 #include "chrome/browser/browser_process.h"
@@ -114,6 +115,7 @@ void ChromeBrowserMainPartsMac::PreCreateMainMessageLoop() {
   }
 #endif  // !BUILDFLAG(CHROME_FOR_TESTING)
 
+#if !BUILDFLAG(ENABLE_CEF)
   // Create the app delegate. This object is intentionally leaked as a global
   // singleton. It is accessed through -[NSApp delegate].
   AppController* app_controller = [[AppController alloc] init];
@@ -122,6 +124,7 @@ void ChromeBrowserMainPartsMac::PreCreateMainMessageLoop() {
   chrome::BuildMainMenu(NSApp, app_controller,
                         l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), false);
   [app_controller mainMenuCreated];
+#endif  // BUILDFLAG(ENABLE_CEF)
 
   ui::WarmScreenCapture();
 
@@ -180,7 +183,9 @@ void ChromeBrowserMainPartsMac::PostProfileInit(Profile* profile,
 }
 
 void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() {
+#if !BUILDFLAG(ENABLE_CEF)
   AppController* appController =
       base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
   [appController didEndMainMessageLoop];
+#endif
 }
diff --git chrome/browser/chrome_content_browser_client.cc chrome/browser/chrome_content_browser_client.cc
index bb3d32d4f4909..7c05c6064dd6e 100644
--- chrome/browser/chrome_content_browser_client.cc
+++ chrome/browser/chrome_content_browser_client.cc
@@ -40,6 +40,7 @@
 #include "base/values.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/features.h"
 #include "chrome/browser/accessibility/accessibility_labels_service.h"
 #include "chrome/browser/accessibility/accessibility_labels_service_factory.h"
 #include "chrome/browser/after_startup_task_utils.h"
@@ -1558,6 +1559,8 @@ ChromeContentBrowserClient::GetPopupNavigationDelegateFactoryForTesting() {
 }
 
 ChromeContentBrowserClient::ChromeContentBrowserClient() {
+  keepalive_timer_.reset(new base::OneShotTimer());
+
 #if BUILDFLAG(ENABLE_PLUGINS)
   extra_parts_.push_back(
       std::make_unique<ChromeContentBrowserClientPluginsPart>());
@@ -1590,6 +1593,11 @@ ChromeContentBrowserClient::~ChromeContentBrowserClient() {
   }
 }
 
+void ChromeContentBrowserClient::CleanupOnUIThread() {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+  keepalive_timer_.reset();
+}
+
 // static
 void ChromeContentBrowserClient::RegisterLocalStatePrefs(
     PrefRegistrySimple* registry) {
@@ -4412,9 +4420,11 @@ void ChromeContentBrowserClient::BrowserURLHandlerCreated(
                           &search::HandleNewTabURLReverseRewrite);
 #endif  // BUILDFLAG(IS_ANDROID)
 
+#if !BUILDFLAG(ENABLE_CEF)
   // chrome: & friends.
   handler->AddHandlerPair(&ChromeContentBrowserClient::HandleWebUI,
                           &ChromeContentBrowserClient::HandleWebUIReverse);
+#endif
 }
 
 base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() {
@@ -6333,7 +6343,7 @@ void ChromeContentBrowserClient::OnNetworkServiceCreated(
 #endif
 }
 
-void ChromeContentBrowserClient::ConfigureNetworkContextParams(
+bool ChromeContentBrowserClient::ConfigureNetworkContextParams(
     content::BrowserContext* context,
     bool in_memory,
     const base::FilePath& relative_partition_path,
@@ -6351,6 +6361,8 @@ void ChromeContentBrowserClient::ConfigureNetworkContextParams(
     network_context_params->user_agent = GetUserAgentBasedOnPolicy(context);
     network_context_params->accept_language = GetApplicationLocale();
   }
+
+  return true;
 }
 
 std::vector<base::FilePath>
@@ -7340,10 +7352,10 @@ void ChromeContentBrowserClient::OnKeepaliveRequestStarted(
   const auto now = base::TimeTicks::Now();
   const auto timeout = GetKeepaliveTimerTimeout(context);
   keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout);
-  if (keepalive_deadline_ > now && !keepalive_timer_.IsRunning()) {
+  if (keepalive_deadline_ > now && !keepalive_timer_->IsRunning()) {
     DVLOG(1) << "Starting a keepalive timer(" << timeout.InSecondsF()
              << " seconds)";
-    keepalive_timer_.Start(
+    keepalive_timer_->Start(
         FROM_HERE, keepalive_deadline_ - now,
         base::BindOnce(
             &ChromeContentBrowserClient::OnKeepaliveTimerFired,
@@ -7362,7 +7374,8 @@ void ChromeContentBrowserClient::OnKeepaliveRequestFinished() {
   --num_keepalive_requests_;
   if (num_keepalive_requests_ == 0) {
     DVLOG(1) << "Stopping the keepalive timer";
-    keepalive_timer_.Stop();
+    if (keepalive_timer_)
+      keepalive_timer_->Stop();
     // This deletes the keep alive handle attached to the timer function and
     // unblock the shutdown sequence.
   }
@@ -7498,7 +7511,7 @@ void ChromeContentBrowserClient::OnKeepaliveTimerFired(
   const auto now = base::TimeTicks::Now();
   const auto then = keepalive_deadline_;
   if (now < then) {
-    keepalive_timer_.Start(
+    keepalive_timer_->Start(
         FROM_HERE, then - now,
         base::BindOnce(&ChromeContentBrowserClient::OnKeepaliveTimerFired,
                        weak_factory_.GetWeakPtr(),
diff --git chrome/browser/chrome_content_browser_client.h chrome/browser/chrome_content_browser_client.h
index 30ee8cf906f70..09e4fa568c05a 100644
--- chrome/browser/chrome_content_browser_client.h
+++ chrome/browser/chrome_content_browser_client.h
@@ -134,6 +134,8 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
 
   ~ChromeContentBrowserClient() override;
 
+  virtual void CleanupOnUIThread();
+
   // TODO(https://crbug.com/787567): This file is about calls from content/ out
   // to chrome/ to get values or notify about events, but both of these
   // functions are from chrome/ to chrome/ and don't involve content/ at all.
@@ -618,7 +620,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
       override;
   void OnNetworkServiceCreated(
       network::mojom::NetworkService* network_service) override;
-  void ConfigureNetworkContextParams(
+  bool ConfigureNetworkContextParams(
       content::BrowserContext* context,
       bool in_memory,
       const base::FilePath& relative_partition_path,
@@ -998,7 +1000,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
 
 #if !BUILDFLAG(IS_ANDROID)
   uint64_t num_keepalive_requests_ = 0;
-  base::OneShotTimer keepalive_timer_;
+  std::unique_ptr<base::OneShotTimer> keepalive_timer_;
   base::TimeTicks keepalive_deadline_;
 #endif
 
diff --git chrome/browser/prefs/browser_prefs.cc chrome/browser/prefs/browser_prefs.cc
index d11c0f1334924..47f8edcf62b3a 100644
--- chrome/browser/prefs/browser_prefs.cc
+++ chrome/browser/prefs/browser_prefs.cc
@@ -13,6 +13,7 @@
 #include "build/build_config.h"
 #include "build/chromecast_buildflags.h"
 #include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/features.h"
 #include "chrome/browser/about_flags.h"
 #include "chrome/browser/accessibility/accessibility_labels_service.h"
 #include "chrome/browser/accessibility/accessibility_ui.h"
@@ -177,6 +178,10 @@
 #include "chrome/browser/background/background_mode_manager.h"
 #endif
 
+#if BUILDFLAG(ENABLE_CEF)
+#include "cef/libcef/browser/prefs/browser_prefs.h"
+#endif
+
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 #include "chrome/browser/accessibility/animation_policy_prefs.h"
 #include "chrome/browser/apps/platform_apps/shortcut_manager.h"
@@ -1369,6 +1374,11 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
 
   // This is intentionally last.
   RegisterLocalStatePrefsForMigration(registry);
+
+#if BUILDFLAG(ENABLE_CEF)
+  // Always call this last.
+  browser_prefs::RegisterLocalStatePrefs(registry);
+#endif
 }
 
 // Register prefs applicable to all profiles.
@@ -1766,6 +1776,10 @@ void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
                               const std::string& locale) {
   RegisterProfilePrefs(registry, locale);
 
+#if BUILDFLAG(ENABLE_CEF)
+  browser_prefs::RegisterProfilePrefs(registry);
+#endif
+
 #if BUILDFLAG(IS_ANDROID)
   ::android::RegisterUserProfilePrefs(registry);
 #endif