diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
index 89287f5..543a625 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
@@ -303,6 +303,20 @@ function testSystemMenuRename() {
   }
 
   /**
+   * Test menu link bundles.
+   */
+  function testMenuBundles() {
+    $this->drupalLogin($this->big_user);
+    $menu = $this->addCustomMenu();
+    $bundles = entity_get_bundles('menu_link');
+    $this->assertTrue($bundles[$menu->id()]);
+    $menus = menu_list_system_menus();
+    $menus[$menu->id()] = $menu->label();
+    ksort($menus);
+    $this->assertIdentical(array_keys($bundles), array_keys($menus));
+  }
+
+  /**
    * Add a menu link using the menu module UI.
    *
    * @param integer $plid Parent menu link id.
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 5daaff5..20c6cad 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -151,6 +151,27 @@ function menu_entity_info_alter(&$entity_info) {
   $entity_info['menu']['controllers']['form'] = array(
     'default' => 'Drupal\menu\MenuFormController',
   );
+  if (isset($entity_info['menu_link'])) {
+    // Upgrade could pass partial definition because config is imported first.
+    $entity_info['menu_link']['entity_keys']['bundle'] = 'menu_name';
+  }
+}
+
+/**
+ * Implements hook_entity_bundle_info().
+ */
+function menu_entity_bundle_info() {
+  $bundles = array();
+  $info = Drupal::entityManager()->getDefinition('menu');
+  $config_names = config_get_storage_names_with_prefix($info['config_prefix'] . '.');
+  foreach ($config_names as $config_name) {
+    $config = config($config_name);
+    $bundles['menu_link'][$config->get('id')] = array(
+      'label' => $config->get('label'),
+    );
+  }
+
+  return $bundles;
 }
 
 /**
