diff --git a/modules/payment/src/Form/PaymentAddForm.php b/modules/payment/src/Form/PaymentAddForm.php
index a7f821ab9..972cf6d92 100644
--- a/modules/payment/src/Form/PaymentAddForm.php
+++ b/modules/payment/src/Form/PaymentAddForm.php
@@ -76,11 +76,18 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $step = $form_state->get('step');
     $step = $step ?: 'payment_gateway';
     $form_state->set('step', $step);
-    if ($step == 'payment_gateway') {
-      $form = $this->buildPaymentGatewayForm($form, $form_state);
-    }
-    elseif ($step == 'payment') {
-      $form = $this->buildPaymentForm($form, $form_state);
+    switch ($step) {
+      case 'payment_gateway':
+        $form = $this->buildPaymentGatewayForm($form, $form_state);
+        break;
+
+      case 'payment_method':
+        $form = $this->buildPaymentMethodForm($form, $form_state);
+        break;
+
+      case 'payment':
+        $form = $this->buildPaymentForm($form, $form_state);
+        break;
     }
 
     return $form;
@@ -98,13 +105,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    *   The built form.
    */
   protected function buildPaymentGatewayForm(array $form, FormStateInterface $form_state) {
-    // @todo
-    // Support adding payments to anonymous orders, by adding support for
-    // creating payment methods directly on this form.
-    if (!$this->order->getCustomerId()) {
-      throw new AccessDeniedHttpException();
-    }
-
     /** @var \Drupal\commerce_payment\PaymentGatewayStorageInterface $payment_gateway_storage */
     $payment_gateway_storage = $this->entityTypeManager->getStorage('commerce_payment_gateway');
     $payment_gateways = $payment_gateway_storage->loadMultipleForOrder($this->order);
@@ -137,14 +137,20 @@ protected function buildPaymentGatewayForm(array $form, FormStateInterface $form
       ],
     ];
 
+    $payment_method_options = [];
     if ($selected_payment_gateway->getPlugin() instanceof SupportsStoredPaymentMethodsInterface) {
       /** @var \Drupal\commerce_payment\PaymentMethodStorageInterface $payment_method_storage */
       $payment_method_storage = $this->entityTypeManager->getStorage('commerce_payment_method');
       $billing_countries = $this->order->getStore()->getBillingCountries();
-      $payment_methods = $payment_method_storage->loadReusable($this->order->getCustomer(), $selected_payment_gateway, $billing_countries);
+      $payment_methods = [];
+      if ($this->order->getCustomerId()) {
+        $payment_methods += $payment_method_storage->loadReusable($this->order->getCustomer(), $selected_payment_gateway, $billing_countries);
+      }
+      if ($this->order->getBillingProfile()) {
+        $payment_methods += $payment_method_storage->loadForProfile($this->order->getBillingProfile(), $selected_payment_gateway);
+      }
       if (!empty($payment_methods)) {
         $selected_payment_method = reset($payment_methods);
-        $payment_method_options = [];
         foreach ($payment_methods as $id => $payment_method) {
           $payment_method_options[$id] = $payment_method->label();
           if ($payment_method->isDefault()) {
@@ -163,22 +169,51 @@ protected function buildPaymentGatewayForm(array $form, FormStateInterface $form
           ],
         ];
       }
+      $form['actions']['add_payment_method'] = [
+        '#type' => 'submit',
+        '#value' => $this->t('Add payment method'),
+        '#weight' => 10,
+      ];
+    }
+
+    if ($payment_method_types = $selected_payment_gateway->getPlugin()->getPaymentMethodTypes()) {
+      /** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentMethodType\PaymentMethodTypeInterface[] $payment_method_types */
+      if (count($payment_method_types) == 1) {
+        $form['payment_method_type'] = [
+          '#type' => 'value',
+          '#value' => reset($payment_method_types)->getPluginId(),
+        ];
+      }
       else {
-        $form['payment_method'] = [
-          '#type' => 'markup',
-          '#markup' => $this->t('There are no reusable payment methods available for the selected gateway.'),
+        $method_type_options = [];
+        foreach ($payment_method_types as $type) {
+          $method_type_options[$type->getPluginId()] = $type->getLabel();
+        }
+        $form['payment_method_type'] = [
+          '#type' => 'radios',
+          '#title' => $this->t('Payment type'),
+          '#options' => $method_type_options,
+          '#default_value' => reset($payment_method_types)->getPluginId(),
+          '#required' => TRUE,
+          '#after_build' => [
+            [get_class($this), 'clearValue'],
+          ],
         ];
-        // Don't allow the form to be submitted.
-        return $form;
       }
     }
 
+    $form['actions']['#type'] = 'actions';
     $form['actions']['submit'] = [
       '#type' => 'submit',
       '#value' => $this->t('Continue'),
       '#button_type' => 'primary',
     ];
 
+    // Hide 'Continue' button if no stored payment method is available.
+    if (empty($payment_method_options) && $selected_payment_gateway->getPlugin() instanceof SupportsStoredPaymentMethodsInterface) {
+      $form['actions']['submit']['#access'] = FALSE;
+    }
+
     return $form;
   }
 
@@ -200,6 +235,42 @@ public static function clearValue(array $element, FormStateInterface $form_state
     return $element;
   }
 
+  /**
+   * Build a payment method creation form.
+   *
+   * @param array $form
+   *   The parent form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the complete form.
+   *
+   * @return array
+   *   The built form.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+   */
+  protected function buildPaymentMethodForm(array $form, FormStateInterface $form_state) {
+    $payment_method_storage = $this->entityTypeManager->getStorage('commerce_payment_method');
+    $payment_method = $payment_method_storage->create([
+      'type' => $form_state->getValue('payment_method_type'),
+      'payment_gateway' => $form_state->getValue('payment_gateway'),
+      'uid' => $this->order->getCustomerId(),
+    ]);
+    $form['add_payment_method'] = [
+      '#type' => 'commerce_payment_gateway_form',
+      '#operation' => 'add-payment-method',
+      '#default_value' => $payment_method,
+    ];
+
+    $form['actions']['#type'] = 'actions';
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => $this->t('Continue'),
+      '#button_type' => 'primary',
+    ];
+
+    return $form;
+  }
+
   /**
    * Builds the form for adding a payment.
    *
@@ -242,6 +313,20 @@ protected function buildPaymentForm(array $form, FormStateInterface $form_state)
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $step = $form_state->get('step');
     if ($step == 'payment_gateway') {
+      if ($form_state->getTriggeringElement()['#id'] === 'edit-actions-add-payment-method') {
+        $next_step = 'payment_method';
+      }
+      else {
+        $next_step = 'payment';
+      }
+      $form_state->set('step', $next_step);
+      $form_state->setRebuild(TRUE);
+    }
+    elseif ($step == 'payment_method') {
+      /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */
+      $payment_method = $form_state->getValue('add_payment_method');
+      $form_state->setValue('payment_method', $payment_method);
+      $form_state->setValue('payment_gateway', $payment_method->getPaymentGatewayId());
       $form_state->set('step', 'payment');
       $form_state->setRebuild(TRUE);
     }
diff --git a/modules/payment/src/PaymentMethodStorage.php b/modules/payment/src/PaymentMethodStorage.php
index 8330b3d2d..7d24b5f29 100644
--- a/modules/payment/src/PaymentMethodStorage.php
+++ b/modules/payment/src/PaymentMethodStorage.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Entity\EntityStorageException;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\profile\Entity\ProfileInterface;
 use Drupal\user\UserInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -114,6 +115,33 @@ public function loadReusable(UserInterface $account, PaymentGatewayInterface $pa
     return $payment_methods;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function loadForProfile(ProfileInterface $profile, PaymentGatewayInterface $payment_gateway) {
+    if (!($payment_gateway->getPlugin() instanceof SupportsStoredPaymentMethodsInterface)) {
+      return [];
+    }
+
+    $query = $this->getQuery();
+    $query
+      ->condition('billing_profile.target_id', $profile->id())
+      ->condition('payment_gateway', $payment_gateway->id())
+      ->condition($query->orConditionGroup()
+        ->condition('expires', $this->time->getRequestTime(), '>')
+        ->condition('expires', 0))
+      ->sort('created', 'DESC');
+    $result = $query->execute();
+    if (empty($result)) {
+      return [];
+    }
+
+    /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface[] $payment_methods */
+    $payment_methods = $this->loadMultiple($result);
+
+    return $payment_methods;
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/modules/payment/src/PaymentMethodStorageInterface.php b/modules/payment/src/PaymentMethodStorageInterface.php
index c4f887026..76c0c5ff5 100644
--- a/modules/payment/src/PaymentMethodStorageInterface.php
+++ b/modules/payment/src/PaymentMethodStorageInterface.php
@@ -5,6 +5,7 @@
 use Drupal\commerce_payment\Entity\PaymentGatewayInterface;
 use Drupal\Core\Entity\ContentEntityStorageInterface;
 use Drupal\user\UserInterface;
+use Drupal\profile\Entity\ProfileInterface;
 
 /**
  * Defines the interface for payment method storage.
@@ -28,4 +29,17 @@
    */
   public function loadReusable(UserInterface $account, PaymentGatewayInterface $payment_gateway, array $billing_countries = []);
 
+  /**
+   * Loads the payment methods for a billing profile and payment gateway.
+   *
+   * @param \Drupal\profile\Entity\ProfileInterface $profile
+   *   The billing profile.
+   * @param \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway
+   *   The payment gateway.
+   *
+   * @return \Drupal\commerce_payment\Entity\PaymentMethodInterface[]
+   *   The payment methods for the given billing profile and payment gateway.
+   */
+  public function loadForProfile(ProfileInterface $profile, PaymentGatewayInterface $payment_gateway);
+
 }
