diff --git a/src/Form/MigrateUpgradeForm.php b/src/Form/MigrateUpgradeForm.php
index fee5e11..ef87b69 100644
--- a/src/Form/MigrateUpgradeForm.php
+++ b/src/Form/MigrateUpgradeForm.php
@@ -567,6 +567,8 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface {
         return $this->buildOverviewForm($form, $form_state);
       case 'credentials':
         return $this->buildCredentialForm($form, $form_state);
+      case 'preupgrade':
+        return $this->buildPreUpgradeForm($form, $form_state);
       case 'confirm':
         return $this->buildConfirmForm($form, $form_state);
       default:
@@ -617,7 +619,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface {
       $form['info_header'] = [
         '#markup' => '<p>' . $this->t('Upgrade a Drupal site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the <a href=":url">upgrading handbook</a> for more detailed information.', [
             ':url' => 'https://www.drupal.org/upgrade/migrate'
-          ]),
+        ]),
       ];
 
       $info[] = $this->t('<strong>Back up the database for this site</strong>. Upgrade will change the database for this site.');
@@ -869,6 +871,145 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface {
    */
   public function submitCredentialForm(array &$form, FormStateInterface $form_state) {
     // Indicate the next step is confirmation.
+    $form_state->setValue('step', 'preupgrade');
+    $form_state->setRebuild();
+  }
+
+  /**
+   * Build the pre upgrade form, displaying an analysis of migrations.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return array
+   *   The form structure.
+   */
+  public function buildPreUpgradeForm(array $form, FormStateInterface $form_state) {
+    $form['#title'] = 'Upgrade analysis report';
+
+    $form['#attributes']['class'][] = 'confirmation';
+
+    $form[$this->getFormName()] = ['#type' => 'hidden', '#value' => 1];
+
+    $table_data = [];
+    $system_data = [];
+    foreach ($form_state->get('migration_ids') as $migration_id) {
+      /** @var MigrationInterface $migration */
+      $migration = Migration::load($migration_id);
+      // Fetch the system data at the first opportunity.
+      if (empty($system_data) && is_a($migration->getSourcePlugin(), '\Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase')) {
+        $system_data = $migration->getSourcePlugin()->getSystemData();
+      }
+      $template_id = $migration->get('template');
+      $source_module = $this->moduleUpgradePaths[$template_id]['source_module'];
+      $destination_module = $this->moduleUpgradePaths[$template_id]['destination_module'];
+      $table_data[$source_module][$destination_module][$migration_id] = $migration->label();
+    }
+    ksort($table_data);
+    foreach ($table_data as $source_module => $destination_module_info) {
+      ksort($table_data[$source_module]);
+    }
+    $unmigrated_source_modules = array_diff_key($system_data['module'], $table_data);
+
+    // Missing migrations.
+    $desc = <<<EOT
+The following items will not be upgraded because there's no defined place 
+for them to move to. See <a href="https://www.drupal.org/upgrade/migrate">
+Upgrading from Drupal 6 or 7 to Drupal 8</a> for ways to fix this.
+EOT;
+    $form['missing_module_list_title'] = [
+      '#type' => 'item',
+      '#title' => t('Missing upgrade paths'),
+      '#description' => t($desc),
+    ];
+    $form['missing_module_list'] = [
+      '#type' => 'table',
+      '#header' => [
+        $this->t('Source'),
+        $this->t('Destination'),
+      ],
+    ];
+    $missing_count = 0;
+    ksort($unmigrated_source_modules);
+    foreach ($unmigrated_source_modules as $source_module => $module_data) {
+      if ($module_data['status']) {
+        $missing_count++;
+        $form['missing_module_list'][$source_module] = [
+          'source_module' => ['#plain_text' => $source_module],
+          'destination_module' => ['#plain_text' => 'Missing'],
+        ];
+      }
+    }
+    // Available migrations.
+    $form['available_module_list'] = [
+      '#tree' => TRUE,
+      '#type' => 'details',
+      '#title' => t('Available upgrade paths'),
+    ];
+
+    $form['available_module_list']['module_list'] = [
+      '#type' => 'table',
+      '#header' => [
+        $this->t('Source'),
+        $this->t('Destination'),
+      ],
+    ];
+
+    $available_count = 0;
+    foreach ($table_data as $source_module => $destination_module_info) {
+      $available_count++;
+      foreach ($destination_module_info as $destination_module => $migration_ids) {
+        $destination_details = [];
+        foreach ($migration_ids as $migration_id => $migration_label) {
+          $destination_details[$migration_label] = [
+            '#type' => 'item',
+            '#plain_text' => t($migration_label),
+          ];
+        }
+      }
+      $form['available_module_list']['module_list'][$source_module] = [
+        'source_module' => ['#plain_text' => $source_module],
+        'destination_module' => $destination_details,
+      ];
+    }
+
+    $form['actions'] = ['#type' => 'actions'];
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => 'Start upgrade',
+      '#description' => 'You can always run additional upgrade later.',
+      '#button_type' => 'primary',
+      '#validate' => [],
+      '#submit' => ['::submitPreUpgradeForm'],
+    ];
+
+    $form['actions']['cancel'] = ConfirmFormHelper::buildCancelLink($this, $this->getRequest());
+
+    $form['counts'] = [
+      '#type' => 'item',
+      '#title' => "<ul><li>" . t($available_count . ' available upgrade paths') .
+      "</li><li>" . t($missing_count . ' missing upgrade paths') . "</li></ul>",
+      '#weight' => -15,
+    ];
+    // By default, render the form using theme_confirm_form().
+    if (!isset($form['#theme'])) {
+      $form['#theme'] = 'confirm_form';
+    }
+    return $form;
+  }
+
+  /**
+   * Pre upgrade form submission handler.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   */
+  public function submitPreUpgradeForm(array &$form, FormStateInterface $form_state) {
+    // Indicate the next step is confirmation.
     $form_state->setValue('step', 'confirm');
     $form_state->setRebuild();
   }
