diff --git a/core/modules/block/block.install b/core/modules/block/block.install
index b1fc925..3c77739 100644
--- a/core/modules/block/block.install
+++ b/core/modules/block/block.install
@@ -336,6 +336,80 @@ function block_update_8008() {
 }
 
 /**
+ * Migrate {block} records to configuration instances.
+ */
+function block_update_8009() {
+  $sandbox['#finished'] = 0;
+
+  if (!isset($sandbox['total'])) {
+    // Initial invocation.
+
+    $sandbox['last'] = 0;
+    $sandbox['count'] = 0;
+
+    $query = db_select('block', 'b');
+    $sandbox['total'] = $query
+      ->condition('b.module', 'block', '<>')
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+  }
+
+  // Subsequent invocations.
+
+  $found = FALSE;
+  if ($sandbox['total']) {
+    // Operate on each block in turn.
+
+    $batch_size = 200;
+    $query = db_select('block', 'b');
+    $query
+      ->fields('b')
+      ->condition('b.module', 'block', '<>')
+      ->condition('b.bid', $sandbox['last'], '>')
+      ->orderBy('b.bid', 'ASC')
+      ->range(0, $batch_size);
+    $blocks = $query->execute();
+
+    foreach ($blocks as $block) {
+      // Try to match a plugin to block.
+      $found = TRUE;
+
+      // This is completely wrong.
+      $plugin_name = 'block.block.' . $block->theme . '.' . str_replace('-', '_', $block->delta);
+      $plugin_id = $block->theme . '.' . str_replace('-', '_', $block->delta);
+      $plugin = $block->module . '_' . str_replace('-', '_', $block->delta) . '_block';
+
+      $entity = config($plugin_name);
+
+      // @todo visibility
+      $entity
+        ->set('id', $plugin_id)
+        ->set('label', $block->title)
+        ->set('region', $block->region)
+        ->set('weight', $block->weight)
+        ->set('module', $block->module)
+        ->set('plugin', $plugin)
+        ->set('status', $block->status);
+      $entity->save();
+
+      $sandbox['count'] += 1;
+      $sandbox['last'] = $block->bid;
+    }
+
+    $sandbox['#finished'] = min(0.99, $sandbox['count'] / $sandbox['total']);
+
+    if (!$found) {
+      // Remove the block table.
+      db_drop_table('block');
+
+      // We're done.
+      $sandbox['#finished'] = 1;
+    }
+  }
+}
+
+/**
  * @} End of "addtogroup updates-7.x-to-8.x".
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php
index b9129e3..2d0002f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php
@@ -8,9 +8,10 @@
 namespace Drupal\system\Tests\Upgrade;
 
 /**
- * Tests upgrading a bare database.
+ * Tests upgrading a filled database with blocks.
  *
- * Loads a bare installation of Drupal 7 and runs the upgrade process on it.
+ * Loads a standard installation of Drupal 7 and runs the upgrade process on 
+ * it.
  */
 class BlockUpgradePathTest extends UpgradePathTestBase {
 
@@ -24,7 +25,7 @@ public static function getInfo() {
 
   public function setUp() {
     $this->databaseDumpFiles = array(
-      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz',
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.filled.standard_all.database.php.gz',
     );
     parent::setUp();
   }
@@ -60,6 +61,12 @@ public function testBlockUpgradeTitleLength() {
     // Confirm that the custom block cannot be created with title longer than
     // the maximum number of characters.
     $this->assertText('Title cannot be longer than 255 characters');
+
+    // Assert that block in correct region.
+    $this->drupalLogout();
+    $this->drupalGet('');
+    $this->assertText('Login');
+
   }
 
 }
