diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index f0c91f3..81b2b7b 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -21,10 +21,12 @@
 #include "base/utils.h"
 #include "class_linker.h"
 #include "dex/invoke_type.h"
-#include "driver/compiler_driver.h"
 #include "driver/compiler_options.h"
-#include "mirror/dex_cache-inl.h"
+#include "gc/space/image_space.h"
+#include "image-inl.h"
+#include "intrinsic_objects.h"
 #include "nodes.h"
+#include "obj_ptr-inl.h"
 #include "scoped_thread_state_change-inl.h"
 #include "thread-current-inl.h"
 
@@ -221,105 +223,223 @@
   return os;
 }
 
+static ObjPtr<mirror::ObjectArray<mirror::Object>> GetBootImageLiveObjects()
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  gc::Heap* heap = Runtime::Current()->GetHeap();
+  const std::vector<gc::space::ImageSpace*>& boot_image_spaces = heap->GetBootImageSpaces();
+  DCHECK(!boot_image_spaces.empty());
+  const ImageHeader& main_header = boot_image_spaces[0]->GetImageHeader();
+  ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects =
+      ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(
+          main_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kBootImageLiveObjects));
+  DCHECK(boot_image_live_objects != nullptr);
+  DCHECK(heap->ObjectIsInBootImageSpace(boot_image_live_objects));
+  return boot_image_live_objects;
+}
+
+static bool CheckIntegerCache(Thread* self,
+                              ClassLinker* class_linker,
+                              ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects,
+                              ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_cache)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  DCHECK(boot_image_cache != nullptr);
+
+  // Since we have a cache in the boot image, both java.lang.Integer and
+  // java.lang.Integer$IntegerCache must be initialized in the boot image.
+  ObjPtr<mirror::Class> cache_class = class_linker->LookupClass(
+      self, "Ljava/lang/Integer$IntegerCache;", /* class_loader */ nullptr);
+  DCHECK(cache_class != nullptr);
+  DCHECK(cache_class->IsInitialized());
+  ObjPtr<mirror::Class> integer_class =
+      class_linker->LookupClass(self, "Ljava/lang/Integer;", /* class_loader */ nullptr);
+  DCHECK(integer_class != nullptr);
+  DCHECK(integer_class->IsInitialized());
+
+  // Check that the current cache is the same as the `boot_image_cache`.
+  ArtField* cache_field = cache_class->FindDeclaredStaticField("cache", "[Ljava/lang/Integer;");
+  DCHECK(cache_field != nullptr);
+  ObjPtr<mirror::ObjectArray<mirror::Object>> current_cache =
+      ObjPtr<mirror::ObjectArray<mirror::Object>>::DownCast(cache_field->GetObject(cache_class));
+  if (current_cache != boot_image_cache) {
+    return false;  // Messed up IntegerCache.cache.
+  }
+
+  // Check that the range matches the boot image cache length.
+  ArtField* low_field = cache_class->FindDeclaredStaticField("low", "I");
+  DCHECK(low_field != nullptr);
+  int32_t low = low_field->GetInt(cache_class);
+  ArtField* high_field = cache_class->FindDeclaredStaticField("high", "I");
+  DCHECK(high_field != nullptr);
+  int32_t high = high_field->GetInt(cache_class);
+  if (boot_image_cache->GetLength() != high - low + 1) {
+    return false;  // Messed up IntegerCache.low or IntegerCache.high.
+  }
+
+  // Check that the elements match the boot image intrinsic objects and check their values as well.
+  ArtField* value_field = integer_class->FindDeclaredInstanceField("value", "I");
+  DCHECK(value_field != nullptr);
+  for (int32_t i = 0, len = boot_image_cache->GetLength(); i != len; ++i) {
+    ObjPtr<mirror::Object> boot_image_object =
+        IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, i);
+    DCHECK(Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(boot_image_object));
+    // No need for read barrier for comparison with a boot image object.
+    ObjPtr<mirror::Object> current_object =
+        boot_image_cache->GetWithoutChecks<kVerifyNone, kWithoutReadBarrier>(i);
+    if (boot_image_object != current_object) {
+      return false;  // Messed up IntegerCache.cache[i]
+    }
+    if (value_field->GetInt(boot_image_object) != low + i) {
+      return false;  // Messed up IntegerCache.cache[i].value.
+    }
+  }
+
+  return true;
+}
+
 void IntrinsicVisitor::ComputeIntegerValueOfLocations(HInvoke* invoke,
                                                       CodeGenerator* codegen,
                                                       Location return_location,
                                                       Location first_argument_location) {
-  if (Runtime::Current()->IsAotCompiler()) {
-    if (codegen->GetCompilerOptions().IsBootImage() ||
-        codegen->GetCompilerOptions().GetCompilePic()) {
-      // TODO(ngeoffray): Support boot image compilation.
-      return;
-    }
-  }
-
-  IntegerValueOfInfo info = ComputeIntegerValueOfInfo();
-
-  // Most common case is that we have found all we needed (classes are initialized
-  // and in the boot image). Bail if not.
-  if (info.integer_cache == nullptr ||
-      info.integer == nullptr ||
-      info.cache == nullptr ||
-      info.value_offset == 0 ||
-      // low and high cannot be 0, per the spec.
-      info.low == 0 ||
-      info.high == 0) {
-    LOG(INFO) << "Integer.valueOf will not be optimized";
+  if (codegen->GetCompilerOptions().IsBootImage()) {
+    // TODO: Implement for boot image. We need access to CompilerDriver::IsImageClass()
+    // to verify that the IntegerCache shall be in the image.
     return;
   }
+  Runtime* runtime = Runtime::Current();
+  gc::Heap* heap = runtime->GetHeap();
+  if (heap->GetBootImageSpaces().empty()) {
+    return;  // Running without boot image, cannot use required boot image objects.
+  }
 
   // The intrinsic will call if it needs to allocate a j.l.Integer.
-  LocationSummary* locations = new (invoke->GetBlock()->GetGraph()->GetAllocator()) LocationSummary(
-      invoke, LocationSummary::kCallOnMainOnly, kIntrinsified);
-  if (!invoke->InputAt(0)->IsConstant()) {
-    locations->SetInAt(0, Location::RequiresRegister());
+  LocationSummary::CallKind call_kind = LocationSummary::kCallOnMainOnly;
+  {
+    Thread* self = Thread::Current();
+    ScopedObjectAccess soa(self);
+    ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects = GetBootImageLiveObjects();
+    ObjPtr<mirror::ObjectArray<mirror::Object>> cache =
+        IntrinsicObjects::GetIntegerValueOfCache(boot_image_live_objects);
+    if (cache == nullptr) {
+      return;  // No cache in the boot image.
+    }
+    if (runtime->UseJitCompilation()) {
+      if (!CheckIntegerCache(self, runtime->GetClassLinker(), boot_image_live_objects, cache)) {
+        return;  // The cache was somehow messed up, probably by using reflection.
+      }
+    } else {
+      DCHECK(runtime->IsAotCompiler());
+      DCHECK(CheckIntegerCache(self, runtime->GetClassLinker(), boot_image_live_objects, cache));
+      if (invoke->InputAt(0)->IsIntConstant()) {
+        int32_t value = invoke->InputAt(0)->AsIntConstant()->GetValue();
+        // Retrieve the `value` from the lowest cached Integer.
+        ObjPtr<mirror::Object> low_integer =
+            IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, 0u);
+        ObjPtr<mirror::Class> integer_class =
+            low_integer->GetClass<kVerifyNone, kWithoutReadBarrier>();
+        ArtField* value_field = integer_class->FindDeclaredInstanceField("value", "I");
+        DCHECK(value_field != nullptr);
+        int32_t low = value_field->GetInt(low_integer);
+        if (static_cast<uint32_t>(value) - static_cast<uint32_t>(low) <
+            static_cast<uint32_t>(cache->GetLength())) {
+          // No call, we shall use direct pointer to the Integer object. Note that we cannot
+          // do this for JIT as the "low" can change through reflection before emitting the code.
+          call_kind = LocationSummary::kNoCall;
+        }
+      }
+    }
   }
-  locations->AddTemp(first_argument_location);
-  locations->SetOut(return_location);
+
+  ArenaAllocator* allocator = invoke->GetBlock()->GetGraph()->GetAllocator();
+  LocationSummary* locations = new (allocator) LocationSummary(invoke, call_kind, kIntrinsified);
+  if (call_kind == LocationSummary::kCallOnMainOnly) {
+    locations->SetInAt(0, Location::RegisterOrConstant(invoke->InputAt(0)));
+    locations->AddTemp(first_argument_location);
+    locations->SetOut(return_location);
+  } else {
+    locations->SetInAt(0, Location::ConstantLocation(invoke->InputAt(0)->AsConstant()));
+    locations->SetOut(Location::RequiresRegister());
+  }
 }
 
-IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo() {
+static int32_t GetIntegerCacheLowFromIntegerCache(Thread* self)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  ObjPtr<mirror::Class> cache_class = Runtime::Current()->GetClassLinker()->LookupClass(
+      self, "Ljava/lang/Integer$IntegerCache;", /* class_loader */ nullptr);
+  DCHECK(cache_class != nullptr);
+  DCHECK(cache_class->IsInitialized());
+  ArtField* low_field = cache_class->FindDeclaredStaticField("low", "I");
+  DCHECK(low_field != nullptr);
+  return low_field->GetInt(cache_class);
+}
+
+static uint32_t CalculateBootImageOffset(ObjPtr<mirror::Object> object)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  gc::Heap* heap = Runtime::Current()->GetHeap();
+  DCHECK(heap->ObjectIsInBootImageSpace(object));
+  return reinterpret_cast<const uint8_t*>(object.Ptr()) - heap->GetBootImageSpaces()[0]->Begin();
+}
+
+inline IntrinsicVisitor::IntegerValueOfInfo::IntegerValueOfInfo()
+    : integer_boot_image_offset(0u),
+      value_offset(0),
+      low(0),
+      length(0u),
+      value_boot_image_offset(0u) {}
+
+IntrinsicVisitor::IntegerValueOfInfo IntrinsicVisitor::ComputeIntegerValueOfInfo(HInvoke* invoke) {
   // Note that we could cache all of the data looked up here. but there's no good
   // location for it. We don't want to add it to WellKnownClasses, to avoid creating global
   // jni values. Adding it as state to the compiler singleton seems like wrong
   // separation of concerns.
   // The need for this data should be pretty rare though.
 
-  // The most common case is that the classes are in the boot image and initialized,
-  // which is easy to generate code for. We bail if not.
+  // Note that at this point we can no longer abort the code generation. Therefore,
+  // we need to provide data that shall not lead to a crash even if the fields were
+  // modified through reflection since ComputeIntegerValueOfLocations() when JITting.
+
+  Runtime* runtime = Runtime::Current();
   Thread* self = Thread::Current();
   ScopedObjectAccess soa(self);
-  Runtime* runtime = Runtime::Current();
-  ClassLinker* class_linker = runtime->GetClassLinker();
-  gc::Heap* heap = runtime->GetHeap();
+  ObjPtr<mirror::ObjectArray<mirror::Object>> boot_image_live_objects = GetBootImageLiveObjects();
+  ObjPtr<mirror::Object> low_integer =
+      IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, 0u);
+  ObjPtr<mirror::Class> integer_class = low_integer->GetClass<kVerifyNone, kWithoutReadBarrier>();
+  ArtField* value_field = integer_class->FindDeclaredInstanceField("value", "I");
+  DCHECK(value_field != nullptr);
+
   IntegerValueOfInfo info;
-  info.integer_cache = class_linker->LookupClass(self,
-                                                 "Ljava/lang/Integer$IntegerCache;",
-                                                 /* class_loader */ nullptr).Ptr();
-  if (info.integer_cache == nullptr || !info.integer_cache->IsInitialized()) {
-    // Optimization only works if the class is initialized.
-    return info;
+  info.integer_boot_image_offset = CalculateBootImageOffset(integer_class);
+  info.value_offset = value_field->GetOffset().Uint32Value();
+  if (runtime->UseJitCompilation()) {
+    // Use the current `IntegerCache.low` for JIT to avoid truly surprising behavior if the
+    // code messes up the `value` field in the lowest cached Integer using reflection.
+    info.low = GetIntegerCacheLowFromIntegerCache(self);
+  } else {
+    // For AOT, the `low_integer->value` should be the same as `IntegerCache.low`.
+    info.low = value_field->GetInt(low_integer);
+    DCHECK_EQ(info.low, GetIntegerCacheLowFromIntegerCache(self));
   }
-  if (!heap->ObjectIsInBootImageSpace(info.integer_cache)) {
-    // Optimization only works if the class is in the boot image.
-    // TODO: Implement the intrinsic for boot image compilation.
-    return info;
-  }
-  info.integer =
-      class_linker->LookupClass(self, "Ljava/lang/Integer;", /* class_loader */ nullptr).Ptr();
-  DCHECK(info.integer != nullptr);
-  DCHECK(info.integer->IsInitialized());  // Must be initialized since IntegerCache is initialized.
-  if (!heap->ObjectIsInBootImageSpace(info.integer)) {
-    // Optimization only works if the class is in the boot image.
-    return info;
+  // Do not look at `IntegerCache.high`, use the immutable length of the cache array instead.
+  info.length = dchecked_integral_cast<uint32_t>(
+      IntrinsicObjects::GetIntegerValueOfCache(boot_image_live_objects)->GetLength());
+
+  if (invoke->InputAt(0)->IsIntConstant()) {
+    int32_t input_value = invoke->InputAt(0)->AsIntConstant()->GetValue();
+    uint32_t index = static_cast<uint32_t>(input_value) - static_cast<uint32_t>(info.low);
+    if (index < static_cast<uint32_t>(info.length)) {
+      ObjPtr<mirror::Object> integer =
+          IntrinsicObjects::GetIntegerValueOfObject(boot_image_live_objects, index);
+      DCHECK(runtime->GetHeap()->ObjectIsInBootImageSpace(integer));
+      info.value_boot_image_offset = CalculateBootImageOffset(integer);
+    } else {
+      info.value_boot_image_offset = 0u;  // Not in the cache.
+    }
+  } else {
+    info.array_data_boot_image_offset =
+        CalculateBootImageOffset(boot_image_live_objects) +
+        IntrinsicObjects::GetIntegerValueOfArrayDataOffset(boot_image_live_objects).Uint32Value();
   }
 
-  ArtField* field = info.integer_cache->FindDeclaredStaticField("cache", "[Ljava/lang/Integer;");
-  CHECK(field != nullptr);
-  info.cache = static_cast<mirror::ObjectArray<mirror::Object>*>(
-      field->GetObject(info.integer_cache).Ptr());
-  if (info.cache == nullptr) {
-    return info;  // Did someone mess up the IntegerCache using reflection?
-  }
-
-  if (!heap->ObjectIsInBootImageSpace(info.cache)) {
-    // Optimization only works if the object is in the boot image.
-    return info;
-  }
-
-  field = info.integer->FindDeclaredInstanceField("value", "I");
-  CHECK(field != nullptr);
-  info.value_offset = field->GetOffset().Int32Value();
-
-  field = info.integer_cache->FindDeclaredStaticField("low", "I");
-  CHECK(field != nullptr);
-  info.low = field->GetInt(info.integer_cache);
-
-  field = info.integer_cache->FindDeclaredStaticField("high", "I");
-  CHECK(field != nullptr);
-  info.high = field->GetInt(info.integer_cache);
-
-  DCHECK_EQ(info.cache->GetLength(), info.high - info.low + 1);
   return info;
 }
 
