diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php
index b0a21db0f0a51a188a19b269146d014386626461..f015f14cf05c234b943d5dc166e2a39603bb7dd6 100644
--- a/core/lib/Drupal/Core/Form/FormState.php
+++ b/core/lib/Drupal/Core/Form/FormState.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Form;
 
 use Drupal\Core\Url;
+use Symfony\Component\HttpFoundation\Response;
 
 /**
  * Stores information about the state of a form.
@@ -579,6 +580,14 @@ public function addValue($property, $value) {
     return $this;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function setResponse(Response $response) {
+    $this->set('response', $response);
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Form/FormStateInterface.php b/core/lib/Drupal/Core/Form/FormStateInterface.php
index 9cabff74ab05ab08ac83528a6d4b91fd68f0e583..3f3fe96137bfc66520bb839702996634961ad42a 100644
--- a/core/lib/Drupal/Core/Form/FormStateInterface.php
+++ b/core/lib/Drupal/Core/Form/FormStateInterface.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Form;
 
 use Drupal\Core\Url;
+use Symfony\Component\HttpFoundation\Response;
 
 /**
  * Provides an interface for an object containing the current state of a form.
@@ -75,6 +76,19 @@ public function setFormState(array $form_state_additions);
    */
   public function setIfNotExists($property, $value);
 
+  /**
+   * Sets a response for this form.
+   *
+   * If a response is set, it will be used during processing and returned
+   * directly. The form will not be rebuilt or redirected.
+   *
+   * @param \Symfony\Component\HttpFoundation\Response $response
+   *   The response to return.
+   *
+   * @return $this
+   */
+  public function setResponse(Response $response);
+
   /**
    * Sets the redirect URL for the form.
    *
diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php
index 4c5d1c75993c5a30e2c075d42376b7135944d526..fb447a2974f1812a8f96e170fdb0cefc646bd80a 100644
--- a/core/lib/Drupal/Core/Form/FormSubmitter.php
+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -79,13 +79,13 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
     $form_state['executed'] = TRUE;
 
     // If no response has been set, process the form redirect.
-    if (!isset($form_state['response']) && $redirect = $this->redirectForm($form_state)) {
-      $form_state['response'] = $redirect;
+    if (!$form_state->has('response') && $redirect = $this->redirectForm($form_state)) {
+      $form_state->setResponse($redirect);
     }
 
     // If there is a response was set, return it instead of continuing.
-    if (isset($form_state['response']) && $form_state['response'] instanceof Response) {
-      return $form_state['response'];
+    if (($response = $form_state->get('response')) && $response instanceof Response) {
+      return $response;
     }
   }
 
diff --git a/core/modules/locale/src/Form/ExportForm.php b/core/modules/locale/src/Form/ExportForm.php
index 5177c694d862bc5f59bad75d07ce5bac11ae741c..1a7772e34644dd34bc35a7f69e0fa415e9dad1c6 100644
--- a/core/modules/locale/src/Form/ExportForm.php
+++ b/core/modules/locale/src/Form/ExportForm.php
@@ -169,7 +169,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
       $response = new BinaryFileResponse($uri);
       $response->setContentDisposition('attachment', $filename);
-      $form_state['response'] = $response;
+      $form_state->setResponse($response);
     }
     else {
       drupal_set_message($this->t('Nothing to export.'));
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php
index 6a23006ae16bfe87b64ed701c64b105d609786ab..63f8ebbe42eaa3643d59c2d92ac3749472cf230d 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxForm.php
@@ -92,7 +92,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php
index 721399e1585258d225da236239daef84bcaa1562..1077c425e7c40dc69bfbd73abfadd371c7d1b100 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesRadiosForm.php
@@ -84,7 +84,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $customiz
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php
index 709a76d371de95e0c300c480a4087f161a775325..70efd25fba71f224b3a31ea2119cda69383f24d3 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestCheckboxesZeroForm.php
@@ -57,7 +57,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $json = T
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     if (!empty($form_state['json'])) {
-      $form_state['response'] = new JsonResponse($form_state['values']);
+      $form_state->setResponse(new JsonResponse($form_state['values']));
     }
     else {
       $form_state['redirect'] = FALSE;
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php
index 3603631fbfdce63001ca6e8cbfdd5c48ba0d2d87..9d37c5af47be130411b5cfea1637ba364d516635 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestColorForm.php
@@ -42,7 +42,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php
index 3555ab674163227fdcbbde54868b8686762e4d8b..da3b8a2de3140c44edf32506d7f1496ef83ab2c8 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestDisabledElementsForm.php
@@ -225,7 +225,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php
index 11bad32ba958172ba56d02917a4a275f7470f2ca..f5ceece94d32e0d10ae0b1c8d0dff43d6c4e9ec1 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestEmailForm.php
@@ -49,7 +49,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php
index 71d8311c85f66085a88403ca69a593a56607e176..e0f9900c658695084ff455e88ed4885c9fc0c337 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestLanguageSelectForm.php
@@ -67,7 +67,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php
index 34f1e52b10c56054282460703eb76e598451d97c..b7119df2c5754a0ca31b16495797b15ea25039f9 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRangeForm.php
@@ -70,7 +70,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php
index eba498b3905285cfbfc70464dedf702d28b3f74d..c7a38f995031445e1703c7aa71261e2c3c2806ee 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestSelectForm.php
@@ -128,7 +128,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php
index 297b60462123ebb482825b037edd60af881d9679..fe95e91bdc5bae40f53c48e78d8de58eba91936d 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestUrlForm.php
@@ -49,7 +49,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    $form_state['response'] = new JsonResponse($form_state['values']);
+    $form_state->setResponse(new JsonResponse($form_state['values']));
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index fede0c1a53bb4eefbd87afe524fa26c3f62d6416..144ed65e38063f2a5572950d63bf92bc650179b5 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -104,7 +104,7 @@ public function testGetFormIdWithBaseForm() {
   }
 
   /**
-   * Tests the handling of $form_state['response'].
+   * Tests the handling of FormStateInterface::$response.
    *
    * @dataProvider formStateResponseProvider
    */
@@ -136,7 +136,7 @@ public function testHandleFormStateResponse($class, $form_state_key) {
     catch (\Exception $e) {
       $this->assertSame('exit', $e->getMessage());
     }
-    $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $form_state['response']);
+    $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $form_state->get('response'));
   }
 
   /**
@@ -150,7 +150,7 @@ public function formStateResponseProvider() {
   }
 
   /**
-   * Tests the handling of a redirect when $form_state['response'] exists.
+   * Tests the handling of a redirect when FormStateInterface::$response exists.
    */
   public function testHandleRedirectWithResponse() {
     $form_id = 'test_form_id';
@@ -176,7 +176,7 @@ public function testHandleRedirectWithResponse() {
       ->method('submitForm')
       ->will($this->returnCallback(function ($form, FormStateInterface $form_state) use ($response, $redirect) {
         // Set both the response and the redirect.
-        $form_state['response'] = $response;
+        $form_state->setResponse($response);
         $form_state['redirect'] = $redirect;
       }));
 
@@ -190,7 +190,7 @@ public function testHandleRedirectWithResponse() {
     catch (\Exception $e) {
       $this->assertSame('exit', $e->getMessage());
     }
-    $this->assertSame($response, $form_state['response']);
+    $this->assertSame($response, $form_state->get('response'));
   }
 
   /**