diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 18b9d27..70347b3 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -327,9 +327,7 @@ function _block_get_renderable_region($list = array()) {
       $key_components = explode('.', $key);
       $id = array_pop($key_components);
       $build[$key] = array(
-        '#block' => $block,
-        '#weight' => $block->get('weight'),
-        '#theme_wrappers' => array('block'),
+        '#entity' => $block,
         '#pre_render' => array('_block_get_renderable_block'),
         '#cache' => array(
           'keys' => array($id, $block->get('module')),
@@ -488,11 +486,12 @@ function block_load($entity_id) {
  *   A renderable array.
  */
 function _block_get_renderable_block($element) {
-  $block = $element['#block'];
+  $block = $element['#entity'];
   // Don't bother to build blocks that aren't accessible.
   if ($element['#access'] = $block->access()) {
     $element += entity_view($block, 'block');
   }
+  unset($element['#entity']);
   return $element;
 }
 
@@ -534,7 +533,7 @@ function block_rebuild() {
 function template_preprocess_block(&$variables) {
   $block_counter = &drupal_static(__FUNCTION__, array());
 
-  $variables['block'] = (object) $variables['elements']['#block_config'];
+  $variables['block'] = (object) $variables['elements']['#block'];
 
   // All blocks get an independent counter for each region.
   if (!isset($block_counter[$variables['block']->region])) {
@@ -565,13 +564,13 @@ function template_preprocess_block(&$variables) {
 
   // We can safely explode on : because we know the Block plugin type manager
   // enforces that delimiter for all derivatives.
-  $parts = explode(':', $variables['elements']['#block']->get('plugin'));
+  $parts = explode(':', $variables['elements']['#block']->plugin);
   $suggestion = 'block';
   while ($part = array_shift($parts)) {
     $variables['theme_hook_suggestions'][] = $suggestion .= '__' . strtr($part, '-', '_');
   }
   // Create a valid HTML ID and make sure it is unique.
-  if ($id = $variables['elements']['#block']->id()) {
+  if ($id = $variables['elements']['#block']->id) {
     $config_id = explode('.', $id);
     $machine_name = array_pop($config_id);
     $variables['block_html_id'] = drupal_html_id('block-' . $machine_name);
diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module
index a3ce18c..ec678d8 100644
--- a/core/modules/block/custom_block/custom_block.module
+++ b/core/modules/block/custom_block/custom_block.module
@@ -8,7 +8,7 @@
 use Drupal\custom_block\Plugin\Core\Entity\CustomBlockType;
 use Drupal\custom_block\Plugin\Core\Entity\CustomBlock;
 use Drupal\custom_block\Plugin\block\block\CustomBlockBlock;
-use Drupal\block\Plugin\Core\Entity\Block;
+use Drupal\block\BlockInterface;
 
 /**
  * Implements hook_menu_local_tasks().
@@ -292,9 +292,9 @@ function custom_block_admin_paths() {
 /**
  * Implements hook_block_view_alter().
  */
-function custom_block_block_view_alter(array &$build, Block $block) {
+function custom_block_block_view_alter(array &$build, BlockInterface $block) {
   // Add contextual links for custom blocks.
-  if ($block->getPlugin() instanceof CustomBlockBlock) {
+  if ($block instanceof CustomBlockBlock) {
     // Move contextual links from inner content to outer wrapper.
     $build['#contextual_links']['custom_block'] = $build['content']['#contextual_links']['custom_block'];
     unset($build['content']['#contextual_links']['custom_block']);
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index 9c90a5a..9cb7355 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -9,7 +9,6 @@
 
 use Drupal\Component\Plugin\PluginBase;
 use Drupal\block\Plugin\Core\Entity\Block;
-use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 
 /**
  * Defines a base block implementation that most blocks plugins will extend.
@@ -21,22 +20,6 @@
 abstract class BlockBase extends PluginBase implements BlockInterface {
 
   /**
-   * The entity using this plugin.
-   *
-   * @var \Drupal\block\Plugin\Core\Entity\Block
-   */
-  protected $entity;
-
-  /**
-   * Overrides \Drupal\Component\Plugin\PluginBase::__construct().
-   */
-  public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery, Block $entity) {
-    parent::__construct($configuration, $plugin_id, $discovery);
-
-    $this->entity = $entity;
-  }
-
-  /**
    * Returns plugin-specific settings for the block.
    *
    * Block plugins only need to override this method if they override the
@@ -142,7 +125,7 @@ public function access() {
     global $user;
 
     // Deny access to disabled blocks.
-    if (!$this->entity->get('status')) {
+    if (!$this->configuration['status']) {
       return FALSE;
     }
 
@@ -150,7 +133,7 @@ public function access() {
     // If a block has no roles associated, it is displayed for every role.
     // For blocks with roles associated, if none of the user's roles matches
     // the settings from this block, access is denied.
-    $visibility = $this->entity->get('visibility');
+    $visibility = $this->configuration['visibility'];
     if (!empty($visibility['role']['roles']) && !array_intersect(array_filter($visibility['role']['roles']), array_keys($user->roles))) {
       // No match.
       return FALSE;
@@ -202,7 +185,7 @@ public function access() {
 
     // Check other modules for block access rules.
     foreach (module_implements('block_access') as $module) {
-      if (module_invoke($module, 'block_access', $this->entity) === FALSE) {
+      if (module_invoke($module, 'block_access', $this) === FALSE) {
         return FALSE;
       }
     }
@@ -489,4 +472,26 @@ public function submit($form, &$form_state) {
    */
   public function blockSubmit($form, &$form_state) {}
 
+  public function buildBlock() {
+    $build = array();
+    if ($content = $this->build()) {
+      $build = array(
+        '#block' => (object) $this->getConfig(),
+        '#theme_wrappers' => array('block'),
+        '#block_config' => array(
+          'id' => $this->configuration['plugin'],
+          'region' => $this->configuration['region'],
+          'module' => $this->configuration['module'],
+          'label' => check_plain($this->configuration['label']),
+        ),
+      );
+      $build['content'] = $content;
+    }
+
+    // All blocks, even when empty, should be available for altering.
+    $id = str_replace(':', '__', $this->configuration['plugin']);
+    drupal_alter(array('block_view', "block_view_$id"), $build, $this);
+    return $build;
+  }
+
 }
diff --git a/core/modules/block/lib/Drupal/block/BlockRenderController.php b/core/modules/block/lib/Drupal/block/BlockRenderController.php
index e1c560e..04dd49b 100644
--- a/core/modules/block/lib/Drupal/block/BlockRenderController.php
+++ b/core/modules/block/lib/Drupal/block/BlockRenderController.php
@@ -23,42 +23,6 @@ public function buildContent(array $entities, array $displays, $view_mode, $lang
   }
 
   /**
-   * Provides entity-specific defaults to the build process.
-   *
-   * @param Drupal\Core\Entity\EntityInterface $entity
-   *   The entity for which the defaults should be provided.
-   * @param string $view_mode
-   *   The view mode that should be used.
-   * @param string $langcode
-   *   (optional) For which language the entity should be prepared, defaults to
-   *   the current content language.
-   *
-   * @return array
-   *   An array of defaults to add into the entity render array.
-   */
-  protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
-    // @todo \Drupal\block\Tests\BlockTest::testCustomBlock() assuemes that a
-    //   block can be rendered without any of its wrappers. To do so, it uses a
-    //   custom view mode, and we choose to only add the wrappers on the default
-    //   view mode, 'block'.
-    if ($view_mode != 'block') {
-      return array();
-    }
-
-    return array(
-      '#block' => $entity,
-      '#weight' => $entity->get('weight'),
-      '#theme_wrappers' => array('block'),
-      '#block_config' => array(
-        'id' => $entity->get('plugin'),
-        'region' => $entity->get('region'),
-        'module' => $entity->get('module'),
-        'label' => check_plain($entity->label()),
-      ),
-    );
-  }
-
-  /**
    * Implements Drupal\Core\Entity\EntityRenderControllerInterface::view().
    */
   public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
@@ -73,15 +37,12 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
     $build = array();
     foreach ($entities as $entity_id => $entity) {
       // Allow blocks to be empty, do not add in the defaults.
-      if ($content = $entity->getPlugin()->build()) {
-        $build[$entity_id] = $this->getBuildDefaults($entity, $view_mode, $langcode);
-      }
-      $build[$entity_id]['content'] = $content;
+      $build[$entity_id] = $entity->getPlugin()->buildBlock();
+      $build[$entity_id]['#weight'] = $entity->get('weight');
 
-      // All blocks, even when empty, should be available for altering.
-      $id = str_replace(':', '__', $entity->get('plugin'));
-      list(, $name) = $entity->id();
-      drupal_alter(array('block_view', "block_view_$id", "block_view_$name"), $build[$entity_id], $entity);
+      list(, $name) = explode('.', $entity->id());
+      $plugin = $entity->getPlugin();
+      drupal_alter(array("block_view_$name"), $build[$entity_id], $plugin);
 
     }
     return $build;
diff --git a/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php b/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php
index 75d82e8..a06d5d5 100644
--- a/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php
+++ b/core/modules/block/lib/Drupal/block/Plugin/Core/Entity/Block.php
@@ -123,8 +123,16 @@ public function getPlugin() {
 
       // Create a plugin instance and store its configuration as settings.
       try {
-        $this->instance = drupal_container()->get('plugin.manager.block')->createInstance($this->plugin, $this->settings, $this);
-        $this->settings += $this->instance->getConfig();
+        $properties = $this->getExportProperties();
+        unset($properties['settings']);
+        $this->instance = drupal_container()->get('plugin.manager.block')->createInstance($this->plugin);
+        $this->instance->getConfig();
+        foreach ($properties as $key => $value) {
+          $this->instance->setConfig($key, $value);
+        }
+        foreach ($this->settings as $key => $value) {
+          $this->instance->setConfig($key, $value);
+        }
       }
       catch (PluginException $e) {
         // Ignore blocks belonging to disabled modules, but re-throw valid
@@ -138,6 +146,14 @@ public function getPlugin() {
   }
 
   /**
+   * Overrides \Drupal\Core\Entity\EntityInterface::label().
+   */
+  public function label($langcode = NULL) {
+    $configuration = $this->getPlugin()->getConfig();
+    return $configuration['label'];
+  }
+
+  /**
    * Overrides \Drupal\Core\Entity\Entity::uri();
    */
   public function uri() {
@@ -159,14 +175,42 @@ public function get($property_name, $langcode = NULL) {
     if ($property_name == 'theme' && !$value) {
       list($value) = explode('.', $this->id());
     }
+    elseif (!in_array($property_name, $this->exportProperties())) {
+      // Support geting plugin specific settings with the get() method.
+      $settings = parent::get('settings');
+      if (isset($settings[$property_name])) {
+        $value = $settings[$property_name];
+      }
+    }
     return $value;
   }
 
   /**
-   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::getExportProperties();
+   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::set();
    */
-  public function getExportProperties() {
-    $names = array(
+  public function set($property_name, $value) {
+    if (!in_array($property_name, $this->exportProperties()) && $property_name != 'settings') {
+      $settings = $this->get('settings');
+      $settings[$property_name] = $value;
+      $this->getPlugin()->setConfig($property_name, $value);
+      parent::set('settings', $settings);
+    }
+    elseif ($property_name == 'settings' && is_array($value)) {
+      $settings = $this->get('settings');
+      foreach ($value as $key => $key_value) {
+        $this->getPlugin()->setConfig($key, $key_value);
+        $settings[$key] = $key_value;
+      }
+      parent::set('settings', $settings);
+    }
+    else {
+      $this->getPlugin()->setConfig($property_name, $value);
+      parent::set($property_name, $value);
+    }
+  }
+
+  protected function exportProperties() {
+    return array(
       'id',
       'label',
       'uuid',
@@ -179,11 +223,25 @@ public function getExportProperties() {
       'settings',
       'langcode',
     );
+  }
+
+  /**
+   * Overrides \Drupal\Core\Config\Entity\ConfigEntityBase::getExportProperties();
+   */
+  public function getExportProperties() {
     $properties = array();
-    foreach ($names as $name) {
+    foreach ($this->exportProperties() as $name) {
       $properties[$name] = $this->get($name);
     }
     return $properties;
   }
 
+  /**
+   * Implements \Drupal\Core\Entity\EntityInterface::save().
+   */
+  public function save() {
+    $this->settings = array_diff_key($this->getPlugin()->getConfig(), $this->getExportProperties());
+    return parent::save();
+  }
+
 }
diff --git a/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php b/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php
index d5dedb9..228f3db 100644
--- a/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php
+++ b/core/modules/block/lib/Drupal/block/Plugin/Type/BlockManager.php
@@ -35,14 +35,7 @@ public function __construct(array $namespaces) {
     $this->discovery = new DerivativeDiscoveryDecorator($this->discovery);
     $this->discovery = new AlterDecorator($this->discovery, 'block');
     $this->discovery = new CacheDecorator($this->discovery, 'block_plugins:' . language(LANGUAGE_TYPE_INTERFACE)->langcode, 'cache_block', CacheBackendInterface::CACHE_PERMANENT, array('block'));
-  }
-
-  /**
-   * Overrides \Drupal\Component\Plugin\PluginManagerBase::createInstance().
-   */
-  public function createInstance($plugin_id, array $configuration = array(), Block $entity = NULL) {
-    $plugin_class = DefaultFactory::getPluginClass($plugin_id, $this->discovery);
-    return new $plugin_class($configuration, $plugin_id, $this->discovery, $entity);
+    $this->factory = new DefaultFactory($this);
   }
 
 }
diff --git a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php
index d707c80..9caf4e1 100644
--- a/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php
+++ b/core/modules/block/lib/Drupal/block/Tests/BlockTemplateSuggestionsUnitTest.php
@@ -44,12 +44,7 @@ function testBlockThemeHookSuggestions() {
     ));
 
     $variables = array();
-    $variables['elements']['#block'] = $block;
-    $variables['elements']['#block_config'] = $block->getPlugin()->getConfig() + array(
-      'id' => $block->get('plugin'),
-      'region' => $block->get('region'),
-      'module' => $block->get('module'),
-    );
+    $variables['elements'] = $block->getPlugin()->buildBlock();
     $variables['elements']['#children'] = '';
     // Test adding a class to the block content.
     $variables['content_attributes']['class'][] = 'test-class';
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index c300ed6..8b066a3 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -12,7 +12,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
-use Drupal\block\Plugin\Core\Entity\Block;
+use Drupal\block\BlockInterface;
 use Drupal\system\Plugin\Core\Entity\Menu;
 use Drupal\system\Plugin\block\block\SystemMenuBlock;
 use Symfony\Component\HttpFoundation\JsonResponse;
@@ -411,9 +411,9 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude,
 /**
  * Implements hook_block_view_alter().
  */
-function menu_block_view_alter(array &$build, Block $block) {
+function menu_block_view_alter(array &$build, BlockInterface $block) {
   // Add contextual links for system menu blocks.
-  if ($block->getPlugin() instanceof SystemMenuBlock) {
+  if ($block instanceof SystemMenuBlock) {
     foreach (element_children($build['content']) as $key) {
       $build['#contextual_links']['menu'] = array('admin/structure/menu/manage', array($build['content'][$key]['#original_link']['menu_name']));
     }
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 8019ff3..a668c61 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -2029,7 +2029,8 @@ function node_form_block_form_alter(&$form, &$form_state) {
  * if the visibility conditions are not met.
  */
 function node_block_access($block) {
-  $visibility = $block->get('visibility');
+  $configuration = $block->getConfig();
+  $visibility = $configuration['visibility'];
   if (!empty($visibility)) {
     $allowed_types = array();
     $node = menu_get_object();
diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module
index 6d31124..1eb27e9 100644
--- a/core/modules/openid/openid.module
+++ b/core/modules/openid/openid.module
@@ -5,6 +5,8 @@
  * Implement OpenID Relying Party support for Drupal
  */
 
+use Drupal\block\BlockInterface;
+
 /**
  * Implements hook_menu().
  */
@@ -158,13 +160,13 @@ function openid_user_logout($account) {
 }
 
 /**
- * Implements hook_block_view_MODULE_DELTA_alter().
+ * Implements hook_block_view_ID_alter().
  *
  * Adds the OpenID login form to the user login block.
  *
  * @see \Drupal\user\Plugin\block\block\UserLoginBlock
  */
-function openid_block_view_user_login_block_alter(&$build, $block) {
+function openid_block_view_user_login_block_alter(&$build, BlockInterface $block) {
   // Only alter the block when it is non-empty, i.e. when no user is logged in.
   if (!isset($build['content']['user_login_form'])) {
     return;
diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module
index cc29255..3ff93fe 100644
--- a/core/modules/overlay/overlay.module
+++ b/core/modules/overlay/overlay.module
@@ -486,7 +486,8 @@ function overlay_block_access($block) {
   // reason for duplicating effort here is performance; we do not even want
   // these blocks to be built if they are not going to be displayed.
   if ($regions_to_render = overlay_get_regions_to_render()) {
-    if (!in_array($block->get('region'), $regions_to_render)) {
+    $configuration = $block->getConfig();
+    if (!in_array($configuration['region'], $regions_to_render)) {
       return FALSE;
     }
   }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 677e5ca..d04d0de 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2637,7 +2637,7 @@ function system_preprocess_block(&$variables) {
 
     // System menu blocks should get the same class as menu module blocks.
     default:
-      if ($variables['elements']['#block']->getPlugin() instanceof SystemMenuBlock) {
+      if ($variables['elements']['#block']->plugin == 'system_main_block') {
         $variables['attributes_array']['role'] = 'navigation';
         $variables['classes_array'][] = 'block-menu';
       }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php b/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php
index 4dbb64d..53beee4 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/block/block/ViewsBlock.php
@@ -42,8 +42,8 @@ class ViewsBlock extends BlockBase {
   /**
    * Overrides \Drupal\Component\Plugin\PluginBase::__construct().
    */
-  public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery, Block $entity) {
-    parent::__construct($configuration, $plugin_id, $discovery, $entity);
+  public function __construct(array $configuration, $plugin_id, DiscoveryInterface $discovery) {
+    parent::__construct($configuration, $plugin_id, $discovery);
 
     list($plugin, $delta) = explode(':', $this->getPluginId());
     list($name, $this->displayID) = explode('-', $delta, 2);
@@ -77,7 +77,7 @@ public function form($form, &$form_state) {
   public function build() {
     $output = $this->view->executeDisplay($this->displayID);
     // Set the label to the title configured in the view.
-    $this->entity->set('label', filter_xss_admin($this->view->getTitle()));
+    $this->configuration['label'] = filter_xss_admin($this->view->getTitle());
     // Before returning the block output, convert it to a renderable array
     // with contextual links.
     $this->addContextualLinks($output);
