diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index e8eb3283aadea686aee5a170c8a68530256ae1e8..d1ae9d78d2efce4952bba7b52f12aa09ee9da439 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -3060,6 +3060,18 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
             factory->empty_string(), 0);
         native_context()->set_break_iterator_internal_current_shared_fun(*info);
       }
+
+      SimpleInstallGetter(isolate_, prototype,
+                          factory->InternalizeUtf8String("breakType"),
+                          Builtins::kBreakIteratorPrototypeBreakType, false);
+
+      {
+        Handle<SharedFunctionInfo> info = SimpleCreateBuiltinSharedFunctionInfo(
+            isolate_, Builtins::kBreakIteratorInternalBreakType,
+            factory->empty_string(), 0);
+        native_context()->set_break_iterator_internal_break_type_shared_fun(
+            *info);
+      }
     }
 
     {
diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h
index 75464801058a4e758a0ac3be1019eb53228a61f0..e9e46c055138b43242ea1f7879cd8937f61a132d 100644
--- a/src/builtins/builtins-definitions.h
+++ b/src/builtins/builtins-definitions.h
@@ -1411,7 +1411,9 @@ namespace internal {
   CPP(BreakIteratorInternalNext)                                       \
   CPP(BreakIteratorPrototypeNext)                                      \
   CPP(BreakIteratorInternalCurrent)                                    \
-  CPP(BreakIteratorPrototypeCurrent)
+  CPP(BreakIteratorPrototypeCurrent)                                   \
+  CPP(BreakIteratorInternalBreakType)                                  \
+  CPP(BreakIteratorPrototypeBreakType)
 #else
 #define BUILTIN_LIST_INTL(CPP, TFJ, TFS)      \
   /* no-op fallback version */                \
diff --git a/src/builtins/builtins-intl.cc b/src/builtins/builtins-intl.cc
index f394f3e22e38689c2e2cc68b49797974c852efc4..af27fd1444cdb1231bbef048ad304677cce2b919 100644
--- a/src/builtins/builtins-intl.cc
+++ b/src/builtins/builtins-intl.cc
@@ -1576,5 +1576,82 @@ BUILTIN(BreakIteratorInternalCurrent) {
   return *isolate->factory()->NewNumberFromInt(break_iterator->current());
 }
 
+BUILTIN(BreakIteratorPrototypeBreakType) {
+  const char* const method = "get Intl.v8BreakIterator.prototype.breakType";
+  HandleScope scope(isolate);
+
+  CHECK_RECEIVER(JSObject, break_iterator_holder, method);
+  if (!Intl::IsObjectOfType(isolate, break_iterator_holder,
+                            Intl::Type::kBreakIterator)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
+                     isolate->factory()->NewStringFromAsciiChecked(method),
+                     break_iterator_holder));
+  }
+
+  Handle<Object> bound_break_type =
+      Handle<Object>(break_iterator_holder->GetEmbedderField(
+                         V8BreakIterator::kBoundBreakTypeIndex),
+                     isolate);
+
+  if (!bound_break_type->IsUndefined(isolate)) {
+    DCHECK(bound_break_type->IsJSFunction());
+    return *bound_break_type;
+  }
+
+  Handle<NativeContext> native_context(isolate->context()->native_context(),
+                                       isolate);
+  Handle<Context> context = isolate->factory()->NewBuiltinContext(
+      native_context, static_cast<int>(V8BreakIterator::ContextSlot::kLength));
+
+  context->set(static_cast<int>(V8BreakIterator::ContextSlot::kV8BreakIterator),
+               *break_iterator_holder);
+
+  Handle<SharedFunctionInfo> info = Handle<SharedFunctionInfo>(
+      native_context->break_iterator_internal_break_type_shared_fun(), isolate);
+  Handle<Map> map = isolate->strict_function_without_prototype_map();
+
+  Handle<JSFunction> new_bound_break_type_function =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(map, info, context);
+  break_iterator_holder->SetEmbedderField(V8BreakIterator::kBoundBreakTypeIndex,
+                                          *new_bound_break_type_function);
+
+  return *new_bound_break_type_function;
+}
+
+BUILTIN(BreakIteratorInternalBreakType) {
+  HandleScope scope(isolate);
+  Handle<Context> context = Handle<Context>(isolate->context(), isolate);
+
+  Handle<JSObject> break_iterator_holder = Handle<JSObject>(
+      JSObject::cast(context->get(
+          static_cast<int>(V8BreakIterator::ContextSlot::kV8BreakIterator))),
+      isolate);
+
+  DCHECK(Intl::IsObjectOfType(isolate, break_iterator_holder,
+                              Intl::Type::kBreakIterator));
+
+  icu::BreakIterator* break_iterator =
+      V8BreakIterator::UnpackBreakIterator(break_iterator_holder);
+  CHECK_NOT_NULL(break_iterator);
+
+  int32_t status = break_iterator->getRuleStatus();
+  // Keep return values in sync with JavaScript BreakType enum.
+  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("none");
+  } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
+    return ReadOnlyRoots(isolate).number_string();
+  } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("letter");
+  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("kana");
+  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("ideo");
+  } else {
+    return *isolate->factory()->NewStringFromStaticChars("unknown");
+  }
+}
+
 }  // namespace internal
 }  // namespace v8
diff --git a/src/contexts.h b/src/contexts.h
index 540e099966ccbb4b4d694899fa44c54a9bb1d76c..edfee80a02b56417b7190a5b47dc29d401b651ee 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -225,6 +225,8 @@ enum ContextLookupFlags {
     break_iterator_internal_next_shared_fun)                                   \
   V(INTL_V8_BREAK_ITERATOR_INTERNAL_CURRENT_SHARED_FUN, SharedFunctionInfo,    \
     break_iterator_internal_current_shared_fun)                                \
+  V(INTL_V8_BREAK_ITERATOR_INTERNAL_BREAK_TYPE_SHARED_FUN, SharedFunctionInfo, \
+    break_iterator_internal_break_type_shared_fun)                             \
   V(JS_ARRAY_PACKED_SMI_ELEMENTS_MAP_INDEX, Map,                               \
     js_array_packed_smi_elements_map)                                          \
   V(JS_ARRAY_HOLEY_SMI_ELEMENTS_MAP_INDEX, Map,                                \
diff --git a/src/js/intl.js b/src/js/intl.js
index 59ba7e22d6b4b467d4f0985ffa5f40d5abea7876..dd043ba2152b37571c8405b628c1de678d214fbd 100644
--- a/src/js/intl.js
+++ b/src/js/intl.js
@@ -55,48 +55,6 @@ macro ANONYMOUS_FUNCTION(fn)
 (0, (fn))
 endmacro
 
-/**
- * Adds bound method to the prototype of the given object.
- */
-function AddBoundMethod(obj, methodName, implementation, length, type,
-                        compat) {
-  %CheckIsBootstrapping();
-  var internalName = %CreatePrivateSymbol(methodName);
-
-  DEFINE_METHOD(
-    obj.prototype,
-    get [methodName]() {
-      if(!IS_RECEIVER(this)) {
-        throw %make_type_error(kIncompatibleMethodReceiver, methodName, this);
-      }
-      var receiver = %IntlUnwrapReceiver(this, type, obj, methodName, compat);
-      if (IS_UNDEFINED(receiver[internalName])) {
-        var boundMethod;
-        if (IS_UNDEFINED(length) || length === 2) {
-          boundMethod =
-            ANONYMOUS_FUNCTION((fst, snd) => implementation(receiver, fst, snd));
-        } else if (length === 1) {
-          boundMethod = ANONYMOUS_FUNCTION(fst => implementation(receiver, fst));
-        } else {
-          boundMethod = ANONYMOUS_FUNCTION((...args) => {
-            // DateTimeFormat.format needs to be 0 arg method, but can still
-            // receive an optional dateValue param. If one was provided, pass it
-            // along.
-            if (args.length > 0) {
-              return implementation(receiver, args[0]);
-            } else {
-              return implementation(receiver);
-            }
-          });
-        }
-        %SetNativeFlag(boundMethod);
-        receiver[internalName] = boundMethod;
-      }
-      return receiver[internalName];
-    }
-  );
-}
-
 function IntlConstruct(receiver, constructor, create, newTarget, args,
                        compat) {
   var locales = args[0];
@@ -1141,17 +1099,6 @@ DEFINE_METHOD(
 );
 
 
-/**
- * Returns type of the current break.
- */
-function breakType(iterator) {
-  return %BreakIteratorBreakType(iterator);
-}
-
-
-AddBoundMethod(GlobalIntlv8BreakIterator, 'breakType', breakType, 0,
-               BREAK_ITERATOR_TYPE, false);
-
 // Save references to Intl objects and methods we use, for added security.
 var savedObjects = {
   __proto__: null,
diff --git a/src/objects/intl-objects.h b/src/objects/intl-objects.h
index 18b6c15e0302c8c54917769bba36720da81c5644..4dce5c19d14b6c6659c5dcf37adc54df7d52a31d 100644
--- a/src/objects/intl-objects.h
+++ b/src/objects/intl-objects.h
@@ -200,6 +200,7 @@ class V8BreakIterator {
   V(kBoundFirst, kPointerSize)     \
   V(kBoundNext, kPointerSize)      \
   V(kBoundCurrent, kPointerSize)   \
+  V(kBoundBreakType, kPointerSize) \
   V(kSize, 0)
 
   DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, BREAK_ITERATOR_FIELDS)
@@ -223,6 +224,7 @@ class V8BreakIterator {
   static const int kBoundFirstIndex = 3;
   static const int kBoundNextIndex = 4;
   static const int kBoundCurrentIndex = 5;
+  static const int kBoundBreakTypeIndex = 6;
 
  private:
   V8BreakIterator();
diff --git a/src/runtime/runtime-intl.cc b/src/runtime/runtime-intl.cc
index d32ee664992bb985e3cc275061487f804473974b..6bb2937aa2f5ffa5fef524b1ed3ca270eb593e65 100644
--- a/src/runtime/runtime-intl.cc
+++ b/src/runtime/runtime-intl.cc
@@ -43,7 +43,6 @@
 #include "unicode/numfmt.h"
 #include "unicode/numsys.h"
 #include "unicode/plurrule.h"
-#include "unicode/rbbi.h"
 #include "unicode/smpdtfmt.h"
 #include "unicode/timezone.h"
 #include "unicode/uchar.h"
@@ -401,37 +400,6 @@ RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
   return *local_object;
 }
 
-RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
-  HandleScope scope(isolate);
-
-  DCHECK_EQ(1, args.length());
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
-
-  icu::BreakIterator* break_iterator =
-      V8BreakIterator::UnpackBreakIterator(break_iterator_holder);
-  CHECK_NOT_NULL(break_iterator);
-
-  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
-  icu::RuleBasedBreakIterator* rule_based_iterator =
-      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
-  int32_t status = rule_based_iterator->getRuleStatus();
-  // Keep return values in sync with JavaScript BreakType enum.
-  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("none");
-  } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
-    return ReadOnlyRoots(isolate).number_string();
-  } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("letter");
-  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("kana");
-  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("ideo");
-  } else {
-    return *isolate->factory()->NewStringFromStaticChars("unknown");
-  }
-}
-
 RUNTIME_FUNCTION(Runtime_ToLocaleDateTime) {
   HandleScope scope(isolate);
 
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
index 7fb86c31ddcc8cff54047c8dd0bede5cbaa68920..262792f3985d805f720a3e2698aaf383e2adad65 100644
--- a/src/runtime/runtime.h
+++ b/src/runtime/runtime.h
@@ -200,7 +200,6 @@ namespace internal {
 #ifdef V8_INTL_SUPPORT
 #define FOR_EACH_INTRINSIC_INTL(F)           \
   F(AvailableLocalesOf, 1, 1)                \
-  F(BreakIteratorBreakType, 1, 1)            \
   F(CanonicalizeLanguageTag, 1, 1)           \
   F(CollatorResolvedOptions, 1, 1)           \
   F(CreateBreakIterator, 3, 1)               \