diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index 51ae6f6..f87ab1d 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -41,6 +41,7 @@
  *     "delete-form" = "/block/{block_content}/delete",
  *     "edit-form" = "/block/{block_content}",
  *     "collection" = "/admin/structure/block/block-content",
+ *     "create" = "/block",
  *   },
  *   translatable = TRUE,
  *   entity_keys = {
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index d52f04d..a63a8b3 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -57,6 +57,7 @@
  *     "canonical" = "/comment/{comment}",
  *     "delete-form" = "/comment/{comment}/delete",
  *     "edit-form" = "/comment/{comment}/edit",
+ *     "create" = "/comment",
  *   },
  *   bundle_entity_type = "comment_type",
  *   field_ui_base_route  = "entity.comment_type.edit_form",
diff --git a/core/modules/node/src/Controller/NodeViewController.php b/core/modules/node/src/Controller/NodeViewController.php
index fce50e1..ba73ba6 100644
--- a/core/modules/node/src/Controller/NodeViewController.php
+++ b/core/modules/node/src/Controller/NodeViewController.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Session\AccountInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
 
 /**
  * Defines a controller to render a single node.
@@ -56,6 +57,17 @@ public function view(EntityInterface $node, $view_mode = 'full', $langcode = NUL
 
     foreach ($node->uriRelationships() as $rel) {
       $url = $node->toUrl($rel);
+
+      // It's not guaranteed that every link relation type also has a
+      // corresponding route. For some, additional modules or configuration may
+      // be necessary.
+      try {
+        $generated_url = $url->toString();
+      }
+      catch (RouteNotFoundException $e) {
+        continue;
+      }
+
       // Add link relationships if the user is authenticated or if the anonymous
       // user has access. Access checking must be done for anonymous users to
       // avoid traffic to inaccessible pages from web crawlers. For
@@ -71,7 +83,7 @@ public function view(EntityInterface $node, $view_mode = 'full', $langcode = NUL
         $build['#attached']['html_head_link'][] = array(
           array(
             'rel' => $rel,
-            'href' => $url->toString(),
+            'href' => $generated_url,
           ),
           TRUE,
         );
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index bb0e36a..5a99d96 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -71,6 +71,7 @@
  *     "edit-form" = "/node/{node}/edit",
  *     "version-history" = "/node/{node}/revisions",
  *     "revision" = "/node/{node}/revisions/{node_revision}/view",
+ *     "create" = "/node",
  *   }
  * )
  */
diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml
index 2def91e..08e7bcc 100644
--- a/core/modules/rest/rest.services.yml
+++ b/core/modules/rest/rest.services.yml
@@ -35,8 +35,23 @@ services:
   logger.channel.rest:
     parent: logger.channel_base
     arguments: ['rest']
+
+  # Event subscribers.
   rest.resource_response.subscriber:
     class: Drupal\rest\EventSubscriber\ResourceResponseSubscriber
     tags:
       - { name: event_subscriber }
     arguments: ['@serializer', '@renderer', '@current_route_match']
+  rest.resource.entity.post_route.subscriber:
+    class: \Drupal\rest\EventSubscriber\EntityResourcePostRouteSubscriber
+    arguments: ['@entity_type.manager']
+    tags:
+      - { name: event_subscriber }
+
+  # @todo Remove in Drupal 9.0.0.
+  rest.path_processor_entity_resource_bc:
+    class: \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC
+    arguments: ['@entity_type.manager']
+    tags:
+      - { name: path_processor_inbound }
+
diff --git a/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php
new file mode 100644
index 0000000..7ffb9ec
--- /dev/null
+++ b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Drupal\rest\EventSubscriber;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Routing\RouteBuildEvent;
+use Drupal\Core\Routing\RoutingEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Generates a 'create' route for an entity type if it has a REST POST route.
+ */
+class EntityResourcePostRouteSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The REST resource config storage.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $resourceConfigStorage;
+
+  /**
+   * Constructs a new EntityResourcePostRouteSubscriber instance.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+    $this->resourceConfigStorage = $entity_type_manager->getStorage('rest_resource_config');
+  }
+
+  /**
+   * Provides routes on route rebuild time.
+   *
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The route build event.
+   */
+  public function onDynamicRouteEvent(RouteBuildEvent $event) {
+    $route_collection = $event->getRouteCollection();
+
+    $resource_configs = $this->resourceConfigStorage->loadMultiple();
+    // Iterate over all REST resource config entities.
+    foreach ($resource_configs as $resource_config) {
+      // We only care about REST resource config entities for the
+      // \Drupal\rest\Plugin\rest\resource\EntityResource plugin.
+      $plugin_id = $resource_config->toArray()['plugin_id'];
+      if (substr($plugin_id, 0, 6) !== 'entity') {
+        continue;
+      }
+
+      $entity_type_id = substr($plugin_id, 7);
+      $rest_post_route_name = "rest.entity.$entity_type_id.POST";
+      if ($rest_post_route = $route_collection->get($rest_post_route_name)) {
+        // Create a route for the 'create' link relation type for this entity type
+        // that uses the same route definition as the REST 'POST' route which use
+        // that entity type.
+        // @see \Drupal\Core\Entity\Entity::toUrl()
+        $entity_create_route_name = "entity.$entity_type_id.create";
+        $route_collection->add($entity_create_route_name, $rest_post_route);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    // Priority -10, to run after \Drupal\rest\Routing\ResourceRoutes, which has
+    // priority 0.
+    $events[RoutingEvents::DYNAMIC][] = ['onDynamicRouteEvent', -10];
+    return $events;
+  }
+
+}
diff --git a/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php b/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php
new file mode 100644
index 0000000..da14ab2
--- /dev/null
+++ b/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\rest\PathProcessor;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Path processor to maintain BC for entity REST resource URLs from Drupal 8.0.
+ */
+class PathProcessorEntityResourceBC implements InboundPathProcessorInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * Creates a new PathProcessorEntityResourceBC instance.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+    $this->entityTypeManager = $entity_type_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processInbound($path, Request $request) {
+    if ($request->getMethod() === 'POST' && strpos($path, '/entity/') === 0) {
+      $parts = explode('/', $path);
+      $entity_type_id = array_pop($parts);
+
+      // Until Drupal 8.3, no entity types specified a link template for the
+      // 'create' link relation type. As of Drupal 8.3, all core content entity
+      // types provide this link relation type. This inbound path processor
+      // provides automatic backwards compatibility: it allows both the old
+      // default from \Drupal\rest\Plugin\rest\resource\EntityResource, i.e.
+      // "/entity/{entity_type}" and the link template specified in a particular
+      // entity type. The former is rewritten to the latter
+      // specific one if it exists)
+      $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
+      if ($entity_type->hasLinkTemplate('create')) {
+        return $entity_type->getLinkTemplate('create');
+      }
+    }
+    return $path;
+  }
+
+}
diff --git a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
index 6a6ddae..b98811c 100644
--- a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
+++ b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
@@ -74,7 +74,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
 
         $default_uris = array(
           'canonical' => "/entity/$entity_type_id/" . '{' . $entity_type_id . '}',
-          'https://www.drupal.org/link-relations/create' => "/entity/$entity_type_id",
+          'create' => "/entity/$entity_type_id",
         );
 
         foreach ($default_uris as $link_relation => $default_uri) {
diff --git a/core/modules/rest/src/Plugin/ResourceBase.php b/core/modules/rest/src/Plugin/ResourceBase.php
index 93684db..773a784 100644
--- a/core/modules/rest/src/Plugin/ResourceBase.php
+++ b/core/modules/rest/src/Plugin/ResourceBase.php
@@ -100,7 +100,15 @@ public function routes() {
 
     $definition = $this->getPluginDefinition();
     $canonical_path = isset($definition['uri_paths']['canonical']) ? $definition['uri_paths']['canonical'] : '/' . strtr($this->pluginId, ':', '/') . '/{id}';
-    $create_path = isset($definition['uri_paths']['https://www.drupal.org/link-relations/create']) ? $definition['uri_paths']['https://www.drupal.org/link-relations/create'] : '/' . strtr($this->pluginId, ':', '/');
+    $create_path = isset($definition['uri_paths']['create']) ? $definition['uri_paths']['create'] : '/' . strtr($this->pluginId, ':', '/');
+    // BC: the REST module originally created the POST URL for a resource by
+    // reading the 'https://www.drupal.org/link-relations/create' URI path from
+    // the plugin annotation. For consistency with entity type definitions, that
+    // then changed to reading the 'create' URI path. For any REST Resource
+    // plugins that were using the old mechanism, we continue to support that.
+    if (!isset($definition['uri_paths']['create']) && isset($definition['uri_paths']['https://www.drupal.org/link-relations/create'])) {
+      $create_path = $definition['uri_paths']['https://www.drupal.org/link-relations/create'];
+    }
 
     $route_name = strtr($this->pluginId, ':', '.');
 
diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
index a1631bd..93abf0a 100644
--- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
+++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
@@ -20,6 +20,7 @@
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 use Symfony\Component\HttpKernel\Exception\HttpException;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
 
 /**
  * Represents entities as resources.
@@ -33,7 +34,7 @@
  *   deriver = "Drupal\rest\Plugin\Deriver\EntityDeriver",
  *   uri_paths = {
  *     "canonical" = "/entity/{entity_type}/{entity}",
- *     "https://www.drupal.org/link-relations/create" = "/entity/{entity_type}"
+ *     "create" = "/entity/{entity_type}"
  *   }
  * )
  */
@@ -369,9 +370,18 @@ public function calculateDependencies() {
   protected function addLinkHeaders(EntityInterface $entity, Response $response) {
     foreach ($entity->getEntityType()->getLinkTemplates() as $relation_name => $link_template) {
       if ($definition = $this->linkRelationTypeManager->getDefinition($relation_name, FALSE)) {
-        $generator_url = $entity->toUrl($relation_name)
-          ->setAbsolute(TRUE)
-          ->toString(TRUE);
+        // It's not guaranteed that every link relation type also has a
+        // corresponding route. For some, additional modules or configuration
+        // may be necessary.
+        try {
+          $generator_url = $entity->toUrl($relation_name)
+            ->setAbsolute(TRUE)
+            ->toString(TRUE);
+        }
+        catch (RouteNotFoundException $e) {
+          continue;
+        }
+
         if ($response instanceof CacheableResponseInterface) {
           $response->addCacheableDependency($generator_url);
         }
diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php
index 8aedfba..33de346 100644
--- a/core/modules/rest/src/Routing/ResourceRoutes.php
+++ b/core/modules/rest/src/Routing/ResourceRoutes.php
@@ -3,16 +3,18 @@
 namespace Drupal\rest\Routing;
 
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Routing\RouteSubscriberBase;
+use Drupal\Core\Routing\RouteBuildEvent;
+use Drupal\Core\Routing\RoutingEvents;
 use Drupal\rest\Plugin\Type\ResourcePluginManager;
 use Drupal\rest\RestResourceConfigInterface;
 use Psr\Log\LoggerInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\Routing\RouteCollection;
 
 /**
  * Subscriber for REST-style routes.
  */
-class ResourceRoutes extends RouteSubscriberBase {
+class ResourceRoutes implements EventSubscriberInterface {
 
   /**
    * The plugin manager for REST plugins.
@@ -54,18 +56,18 @@ public function __construct(ResourcePluginManager $manager, EntityTypeManagerInt
   /**
    * Alters existing routes for a specific collection.
    *
-   * @param \Symfony\Component\Routing\RouteCollection $collection
-   *   The route collection for adding routes.
-   * @return array
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The route build event.
    */
-  protected function alterRoutes(RouteCollection $collection) {
+  public function onDynamicRouteEvent(RouteBuildEvent $event) {
     // Iterate over all enabled REST resource configs.
     /** @var \Drupal\rest\RestResourceConfigInterface[] $resource_configs */
     $resource_configs = $this->resourceConfigStorage->loadMultiple();
     // Iterate over all enabled resource plugins.
     foreach ($resource_configs as $resource_config) {
       $resource_routes = $this->getRoutesForResourceConfig($resource_config);
-      $collection->addCollection($resource_routes);
+      $event->getRouteCollection()
+        ->addCollection($resource_routes);
     }
   }
 
@@ -123,4 +125,12 @@ protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_
     return $collection;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[RoutingEvents::DYNAMIC] = 'onDynamicRouteEvent';
+    return $events;
+  }
+
 }
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 603fb35..2a59169 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -650,6 +650,16 @@ public function testPost() {
     $this->assertResourceResponse(201, FALSE, $response);
     $this->assertSame([str_replace($this->entity->id(), static::$secondCreatedEntityId, $this->entity->toUrl('canonical')->setAbsolute(TRUE)->toString())], $response->getHeader('Location'));
     $this->assertFalse($response->hasHeader('X-Drupal-Cache'));
+
+    // BC: old default POST URLs have their path updated by the inbound path
+    // processor \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC to the
+    // new URL, which is derived from the 'create' link template if an entity
+    // type specifies it.
+    if ($this->entity->getEntityType()->hasLinkTemplate('create')) {
+      $old_url = Url::fromUri('base:entity/' . static::$entityTypeId);
+      $response = $this->request('POST', $old_url, $request_options);
+      $this->assertResourceResponse(201, FALSE, $response);
+    }
   }
 
   /**
@@ -1015,8 +1025,8 @@ protected function getUrl() {
    *   The URL to POST to.
    */
   protected function getPostUrl() {
-    $has_canonical_url = $this->entity->hasLinkTemplate('https://www.drupal.org/link-relations/create');
-    return $has_canonical_url ? $this->entity->toUrl() : Url::fromUri('base:entity/' . static::$entityTypeId);
+    $has_create_url = $this->entity->hasLinkTemplate('create');
+    return $has_create_url ? Url::fromUri('internal:' . $this->entity->getEntityType()->getLinkTemplate('create')) : Url::fromUri('base:entity/' . static::$entityTypeId);
   }
 
   /**
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
index a603f53..f169bd7 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
@@ -45,6 +45,7 @@
  *     "add-form" = "/entity_test/add",
  *     "edit-form" = "/entity_test/manage/{entity_test}/edit",
  *     "delete-form" = "/entity_test/delete/entity_test/{entity_test}",
+ *     "create" = "/entity_test",
  *   },
  *   field_ui_base_route = "entity.entity_test.admin_form",
  * )
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php
index c668bd3..e6cb542 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php
@@ -41,6 +41,7 @@
  *     "add-form" = "/entity_test_with_bundle/add/{entity_test_bundle}",
  *     "edit-form" = "/entity_test_with_bundle/{entity_test_with_bundle}/edit",
  *     "delete-form" = "/entity_test_with_bundle/{entity_test_with_bundle}/delete",
+ *     "create" = "/entity_test_with_bundle",
  *   },
  * )
  */
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php
index 4f4f4f1..33054fb 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php
@@ -40,6 +40,7 @@
  *     "delete-form" = "/entity_test/delete/entity_test_revlog/{entity_test_revlog}",
  *     "edit-form" = "/entity_test_revlog/manage/{entity_test_revlog}/edit",
  *     "revision" = "/entity_test_revlog/{entity_test_revlog}/revision/{entity_test_revlog_revision}/view",
+ *     "create" = "/entity_test_revlog",
  *   }
  * )
  */
diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php
index 5b0072b..b72f74e 100644
--- a/core/modules/taxonomy/src/Entity/Term.php
+++ b/core/modules/taxonomy/src/Entity/Term.php
@@ -46,6 +46,7 @@
  *     "canonical" = "/taxonomy/term/{taxonomy_term}",
  *     "delete-form" = "/taxonomy/term/{taxonomy_term}/delete",
  *     "edit-form" = "/taxonomy/term/{taxonomy_term}/edit",
+ *     "create" = "/taxonomy/term",
  *   },
  *   permission_granularity = "bundle"
  * )
diff --git a/core/modules/user/src/Entity/User.php b/core/modules/user/src/Entity/User.php
index 062af44..3be0e79 100644
--- a/core/modules/user/src/Entity/User.php
+++ b/core/modules/user/src/Entity/User.php
@@ -51,6 +51,7 @@
  *     "edit-form" = "/user/{user}/edit",
  *     "cancel-form" = "/user/{user}/cancel",
  *     "collection" = "/admin/people",
+ *     "create" = "/user",
  *   },
  *   field_ui_base_route = "entity.user.admin_form",
  *   common_reference_target = TRUE
