diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc
index 59cc1c6..ffa98ca 100644
--- a/core/modules/image/image.admin.inc
+++ b/core/modules/image/image.admin.inc
@@ -5,6 +5,8 @@
  * Administration pages for image settings.
  */
 
+use Drupal\image\Plugin\Core\Entity\ImageStyle;
+
 /**
  * Menu callback; Listing of all current image styles.
  */
@@ -24,242 +26,6 @@ function image_style_list() {
 }
 
 /**
- * Form builder; Edit an image style name and effects order.
- *
- * @param $form_state
- *   An associative array containing the current state of the form.
- * @param $style
- *   An image style array.
- * @ingroup forms
- * @see image_style_form_submit()
- */
-function image_style_form($form, &$form_state, $style) {
-  $title = t('Edit style %name', array('%name' => $style->label()));
-  drupal_set_title($title, PASS_THROUGH);
-
-  $form_state['image_style'] = $style;
-  $form['#tree'] = TRUE;
-  $form['#attached']['css'][drupal_get_path('module', 'image') . '/css/image.admin.css'] = array();
-
-  // Show the thumbnail preview.
-  $form['preview'] = array(
-    '#type' => 'item',
-    '#title' => t('Preview'),
-    '#markup' => theme('image_style_preview', array('style' => $style)),
-  );
-
-  $form['label'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Administrative label'),
-    '#default_value' => $style->label(),
-    '#required' => TRUE,
-  );
-  $form['name'] = array(
-    '#type' => 'machine_name',
-    '#default_value' => $style->id(),
-    '#machine_name' => array(
-      'exists' => 'image_style_load',
-    ),
-    '#required' => TRUE,
-  );
-
-  // Build the list of existing image effects for this image style.
-  $form['effects'] = array(
-    '#theme' => 'image_style_effects',
-  );
-  if (!empty($style->effects)) {
-    foreach ($style->effects as $key => $effect) {
-      $form['effects'][$key]['#weight'] = isset($form_state['input']['effects']) ? $form_state['input']['effects'][$key]['weight'] : NULL;
-      $form['effects'][$key]['label'] = array(
-        '#markup' => check_plain($effect['label']),
-      );
-      $form['effects'][$key]['summary'] = array(
-        '#markup' => isset($effect['summary theme']) ? theme($effect['summary theme'], array('data' => $effect['data'])) : '',
-      );
-      $form['effects'][$key]['weight'] = array(
-        '#type' => 'weight',
-        '#title' => t('Weight for @title', array('@title' => $effect['label'])),
-        '#title_display' => 'invisible',
-        '#default_value' => $effect['weight'],
-      );
-
-      $links = array();
-      if (isset($effect['form callback'])) {
-        $links['edit'] = array(
-          'title' => t('edit'),
-          'href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key,
-        );
-      }
-      $links['delete'] = array(
-        'title' => t('delete'),
-        'href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key . '/delete',
-      );
-      $form['effects'][$key]['operations'] = array(
-        '#type' => 'operations',
-        '#links' => $links,
-      );
-      $form['effects'][$key]['configure'] = array(
-        '#type' => 'link',
-        '#title' => t('edit'),
-        '#href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key,
-        '#access' => isset($effect['form callback']),
-      );
-      $form['effects'][$key]['remove'] = array(
-        '#type' => 'link',
-        '#title' => t('delete'),
-        '#href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key . '/delete',
-      );
-    }
-  }
-
-  // Build the new image effect addition form and add it to the effect list.
-  $new_effect_options = array();
-  foreach (image_effect_definitions() as $effect => $definition) {
-    $new_effect_options[$effect] = $definition['label'];
-  }
-  $form['effects']['new'] = array(
-    '#tree' => FALSE,
-    '#weight' => isset($form_state['input']['weight']) ? $form_state['input']['weight'] : NULL,
-  );
-  $form['effects']['new']['new'] = array(
-    '#type' => 'select',
-    '#title' => t('Effect'),
-    '#title_display' => 'invisible',
-    '#options' => $new_effect_options,
-    '#empty_option' => t('Select a new effect'),
-  );
-  $form['effects']['new']['weight'] = array(
-    '#type' => 'weight',
-    '#title' => t('Weight for new effect'),
-    '#title_display' => 'invisible',
-    '#default_value' => count($form['effects']) - 1,
-  );
-  $form['effects']['new']['add'] = array(
-    '#type' => 'submit',
-    '#value' => t('Add'),
-    '#validate' => array('image_style_form_add_validate'),
-    '#submit' => array('image_style_form_submit', 'image_style_form_add_submit'),
-  );
-
-  // Show the Override or Submit button for this style.
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Update style'),
-  );
-
-  return $form;
-}
-
-/**
- * Validate handler for adding a new image effect to an image style.
- */
-function image_style_form_add_validate($form, &$form_state) {
-  if (!$form_state['values']['new']) {
-    form_error($form['effects']['new']['new'], t('Select an effect to add.'));
-  }
-}
-
-/**
- * Submit handler for adding a new image effect to an image style.
- */
-function image_style_form_add_submit($form, &$form_state) {
-  $style = $form_state['image_style'];
-  // Check if this field has any configuration options.
-  $effect = image_effect_definition_load($form_state['values']['new']);
-
-  // Load the configuration form for this option.
-  if (isset($effect['form callback'])) {
-    $path = 'admin/config/media/image-styles/manage/' . $style->id() . '/add/' . $form_state['values']['new'];
-    $form_state['redirect'] = array($path, array('query' => array('weight' => $form_state['values']['weight'])));
-  }
-  // If there's no form, immediately add the image effect.
-  else {
-    $effect = array(
-      'name' => $effect['name'],
-      'data' => array(),
-      'weight' => $form_state['values']['weight'],
-    );
-    image_effect_save($style, $effect);
-    drupal_set_message(t('The image effect was successfully applied.'));
-  }
-}
-
-/**
- * Submit handler for saving an image style.
- */
-function image_style_form_submit($form, &$form_state) {
-  $style = $form_state['image_style'];
-
-  // Update image effect weights.
-  if (!empty($form_state['values']['effects'])) {
-    foreach ($form_state['values']['effects'] as $ieid => $effect_data) {
-      if (isset($style->effects[$ieid])) {
-        $effect = array(
-          'name' => $style->effects[$ieid]['name'],
-          'data' => $style->effects[$ieid]['data'],
-          'weight' => $effect_data['weight'],
-          'ieid' => $ieid,
-        );
-        $style->effects[$ieid] = $effect;
-      }
-    }
-  }
-
-  $style->set('name', $form_state['values']['name']);
-  $style->set('label', $form_state['values']['label']);
-  $status = $style->save();
-
-  if ($status == SAVED_UPDATED) {
-    drupal_set_message(t('Changes to the style have been saved.'));
-  }
-  $form_state['redirect'] = 'admin/config/media/image-styles/manage/' . $style->id();
-}
-
-/**
- * Form builder; Form for adding a new image style.
- *
- * @ingroup forms
- * @see image_style_add_form_submit()
- */
-function image_style_add_form($form, &$form_state) {
-  $form['label'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Administrative label'),
-    '#default_value' => '',
-    '#required' => TRUE,
-  );
-  $form['name'] = array(
-    '#type' => 'machine_name',
-    '#machine_name' => array(
-      'exists' => 'image_style_load',
-    ),
-    '#default_value' => '',
-    '#required' => TRUE,
-  );
-
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Create new style'),
-  );
-
-  return $form;
-}
-
-/**
- * Submit handler for adding a new image style.
- */
-function image_style_add_form_submit($form, &$form_state) {
-  $style = entity_create('image_style', array(
-    'name' => $form_state['values']['name'],
-    'label' => $form_state['values']['label'],
-  ));
-  $style->save();
-  drupal_set_message(t('Style %name was created.', array('%name' => $style->label())));
-  $form_state['redirect'] = 'admin/config/media/image-styles/manage/' . $style->id();
-}
-
-/**
  * Form builder; Form for adding and editing image effects.
  *
  * This form is used universally for editing all image effects. Each effect adds
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index e8dc3d4..9145835 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -135,29 +135,19 @@ function image_menu() {
     'file' => 'image.admin.inc',
   );
   $items['admin/config/media/image-styles/add'] = array(
-    'title' => 'Add style',
-    'description' => 'Add a new image style.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('image_style_add_form'),
-    'access arguments' => array('administer image styles'),
+    'title' => 'Add image style',
+    'route_name' => 'image_style_add',
     'type' => MENU_LOCAL_ACTION,
     'weight' => 2,
-    'file' => 'image.admin.inc',
   );
   $items['admin/config/media/image-styles/manage/%image_style'] = array(
     'title' => 'Edit style',
-    'title callback' => 'entity_page_label',
-    'title arguments' => array(5),
     'description' => 'Configure an image style.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('image_style_form', 5),
-    'access arguments' => array('administer image styles'),
-    'file' => 'image.admin.inc',
+    'route_name' => 'image_style_edit',
   );
   $items['admin/config/media/image-styles/manage/%image_style/edit'] = array(
     'title' => 'Edit',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/config/media/image-styles/manage/%image_style/delete'] = array(
     'title' => 'Delete',
diff --git a/core/modules/image/image.routing.yml b/core/modules/image/image.routing.yml
index 0aa23ba..af204fd 100644
--- a/core/modules/image/image.routing.yml
+++ b/core/modules/image/image.routing.yml
@@ -1,3 +1,17 @@
+image_style_add:
+  pattern: '/admin/config/media/image-styles/add'
+  defaults:
+    _entity_form: image_style.add
+  requirements:
+    _permission: 'administer image styles'
+
+image_style_edit:
+  pattern: '/admin/config/media/image-styles/manage/{image_style}'
+  defaults:
+    _entity_form: image_style.edit
+  requirements:
+    _permission: 'administer image styles'
+
 image_style_delete:
   pattern: 'admin/config/media/image-styles/manage/{image_style}/delete'
   defaults:
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleAddFormController.php b/core/modules/image/lib/Drupal/image/ImageStyleAddFormController.php
new file mode 100644
index 0000000..996c5df
--- /dev/null
+++ b/core/modules/image/lib/Drupal/image/ImageStyleAddFormController.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\image\ImageStyleAddFormController.
+ */
+
+namespace Drupal\image;
+
+use Drupal\Core\Entity\EntityFormController;
+
+/**
+ * Base form controller for image style addition forms.
+ */
+class ImageStyleAddFormController extends EntityFormController {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, array &$form_state) {
+    $form = parent::form($form, $form_state);
+
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Administrative label'),
+      '#default_value' => $this->entity->label(),
+      '#required' => TRUE,
+      '#weight' => 20,
+    );
+    $form['name'] = array(
+      '#type' => 'machine_name',
+      '#machine_name' => array(
+        'exists' => 'image_style_load',
+      ),
+      '#default_value' => $this->entity->id(),
+      '#required' => TRUE,
+      '#weight' => 30,
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, array &$form_state) {
+    $this->entity->save();
+    drupal_set_message(t('Style %name was created.', array('%name' => $this->entity->label())));
+    $uri = $this->entity->uri();
+    watchdog('image', 'Style %name was created.', array('%name' => $this->entity->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path']));
+    $form_state['redirect'] = 'admin/config/media/image-styles/manage/' . $this->entity->id();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function actions(array $form, array &$form_state) {
+    $actions = parent::actions($form, $form_state);
+
+    $actions['submit']['#value'] = t('Create new style');
+    unset($actions['delete']);
+
+    return $actions;
+  }
+
+}
diff --git a/core/modules/image/lib/Drupal/image/ImageStyleFormController.php b/core/modules/image/lib/Drupal/image/ImageStyleFormController.php
new file mode 100644
index 0000000..835cbe8
--- /dev/null
+++ b/core/modules/image/lib/Drupal/image/ImageStyleFormController.php
@@ -0,0 +1,221 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\image\ImageStyleFormController.
+ */
+
+namespace Drupal\image;
+
+use Drupal\Core\Entity\EntityFormController;
+
+/**
+ * Base form controller for image style edit forms.
+ */
+class ImageStyleFormController extends EntityFormController {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, array &$form_state) {
+    $form = parent::form($form, $form_state);
+    $style = $this->entity;
+
+    // @todo Remove drupal_set_title() in http://drupal.org/node/1981644
+    $title = t('Edit style %name', array('%name' => $style->label()));
+    drupal_set_title($title, PASS_THROUGH);
+
+    $form['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Image style name'),
+      '#default_value' => $style->label(),
+      '#required' => TRUE,
+      '#weight' => 20,
+    );
+    $form['name'] = array(
+      '#type' => 'machine_name',
+      '#machine_name' => array(
+        'exists' => 'image_style_load',
+      ),
+      '#default_value' => $style->id(),
+      '#required' => TRUE,
+      '#weight' => 30,
+    );
+
+    $form['#tree'] = TRUE;
+    $form['#attached']['css'][drupal_get_path('module', 'image') . '/css/image.admin.css'] = array();
+
+    // Show the thumbnail preview.
+    form_load_include($form_state, 'inc', 'image', 'image.admin');
+    $form['preview'] = array(
+      '#type' => 'item',
+      '#title' => t('Preview'),
+      '#markup' => theme('image_style_preview', array('style' => $style)),
+      '#weight' => 10,
+    );
+
+    // Build the list of existing image effects for this image style.
+    $form['effects'] = array(
+      '#theme' => 'image_style_effects',
+      '#weight' => 40,
+    );
+
+    if (!empty($style->effects)) {
+      foreach ($style->effects as $key => $effect) {
+        $form['effects'][$key]['#weight'] = isset($form_state['input']['effects']) ? $form_state['input']['effects'][$key]['weight'] : NULL;
+        $form['effects'][$key]['label'] = array(
+          '#markup' => check_plain($effect['label']),
+        );
+        $form['effects'][$key]['name'] = array(
+          '#type' => 'value',
+          '#value' => $effect['name'],
+        );
+        $form['effects'][$key]['data'] = array(
+          '#type' => 'value',
+          '#value' => $effect['data'],
+        );
+        $form['effects'][$key]['summary'] = array(
+          '#markup' => isset($effect['summary theme']) ? theme($effect['summary theme'], array('data' => $effect['data'])) : '',
+        );
+        $form['effects'][$key]['weight'] = array(
+          '#type' => 'weight',
+          '#title' => t('Weight for @title', array('@title' => $effect['label'])),
+          '#title_display' => 'invisible',
+          '#default_value' => $effect['weight'],
+        );
+
+        $links = array();
+        if (isset($effect['form callback'])) {
+          $links['edit'] = array(
+            'title' => t('edit'),
+            'href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key,
+          );
+        }
+        $links['delete'] = array(
+          'title' => t('delete'),
+          'href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key . '/delete',
+        );
+        $form['effects'][$key]['operations'] = array(
+          '#type' => 'operations',
+          '#links' => $links,
+        );
+        $form['effects'][$key]['configure'] = array(
+          '#type' => 'link',
+          '#title' => t('edit'),
+          '#href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key,
+          '#access' => isset($effect['form callback']),
+        );
+        $form['effects'][$key]['remove'] = array(
+          '#type' => 'link',
+          '#title' => t('delete'),
+          '#href' => 'admin/config/media/image-styles/manage/' . $style->id() . '/effects/' . $key . '/delete',
+        );
+      }
+    }
+
+    // Build the new image effect addition form and add it to the effect list.
+    $new_effect_options = array();
+    foreach (image_effect_definitions() as $effect => $definition) {
+      $new_effect_options[$effect] = $definition['label'];
+    }
+    $form['effects']['new'] = array(
+      '#tree' => FALSE,
+      '#weight' => isset($form_state['input']['weight']) ? $form_state['input']['weight'] : NULL,
+    );
+    $form['effects']['new']['new'] = array(
+      '#type' => 'select',
+      '#title' => t('Effect'),
+      '#title_display' => 'invisible',
+      '#options' => $new_effect_options,
+      '#empty_option' => t('Select a new effect'),
+    );
+    $form['effects']['new']['weight'] = array(
+      '#type' => 'weight',
+      '#title' => t('Weight for new effect'),
+      '#title_display' => 'invisible',
+      '#default_value' => count($form['effects']) - 1,
+    );
+    $form['effects']['new']['add'] = array(
+      '#type' => 'submit',
+      '#value' => t('Add'),
+      '#validate' => array(array($this, 'effectValidate')),
+      '#submit' => array(array($this, 'effectSave')),
+    );
+
+    return $form;
+  }
+
+  /**
+   * Validate handler for image effect.
+   */
+  public function effectValidate($form, &$form_state) {
+    if (!$form_state['values']['new']) {
+      form_error($form['effects']['new']['new'], t('Select an effect to add.'));
+    }
+  }
+
+  /**
+   * Submit handler for image effect.
+   */
+  public function effectSave($form, &$form_state) {
+    $style = $this->entity;
+
+    // Update image effect weights.
+    if (!empty($form_state['values']['effects'])) {
+      foreach ($form_state['values']['effects'] as $ieid => $effect_data) {
+        if (isset($style->effects[$ieid])) {
+          $effect = array(
+            'name' => $style->effects[$ieid]['name'],
+            'data' => $style->effects[$ieid]['data'],
+            'weight' => $effect_data['weight'],
+            'ieid' => $ieid,
+          );
+          $style->effects[$ieid] = $effect;
+        }
+      }
+    }
+
+    // Check if this field has any configuration options.
+    $effect = image_effect_definition_load($form_state['values']['new']);
+
+    // Load the configuration form for this option.
+    if (isset($effect['form callback'])) {
+      $path = 'admin/config/media/image-styles/manage/' . $style->id() . '/add/' . $form_state['values']['new'];
+      $form_state['redirect'] = array($path, array('query' => array('weight' => $form_state['values']['weight'])));
+    }
+    // If there's no form, immediately add the image effect.
+    else {
+      $effect = array(
+        'name' => $effect['name'],
+        'data' => array(),
+        'weight' => $form_state['values']['weight'],
+      );
+      image_effect_save($style, $effect);
+      drupal_set_message(t('The image effect was successfully applied.'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, array &$form_state) {
+    $this->entity->save();
+    drupal_set_message(t('Changes to the style have been saved.'));
+    $uri = $this->entity->uri();
+    watchdog('image', 'Style %label has been updated.', array('%label' => $this->entity->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path']));
+    $form_state['redirect'] = 'admin/config/media/image-styles/manage/' . $this->entity->id();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function actions(array $form, array &$form_state) {
+    $actions = parent::actions($form, $form_state);
+
+    $actions['submit']['#value'] = t('Update style');
+    unset($actions['delete']);
+
+    return $actions;
+  }
+
+}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
index 60f020e..8150d6d 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/Core/Entity/ImageStyle.php
@@ -20,7 +20,11 @@
  *   label = @Translation("Image style"),
  *   module = "image",
  *   controllers = {
- *     "storage" = "Drupal\image\ImageStyleStorageController"
+ *     "storage" = "Drupal\image\ImageStyleStorageController",
+ *     "form" = {
+ *       "add" = "Drupal\image\ImageStyleAddFormController",
+ *       "edit" = "Drupal\image\ImageStyleFormController"
+ *     }
  *   },
  *   uri_callback = "image_style_entity_uri",
  *   config_prefix = "image.style",
