diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index 61b018a..65f76c5 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -180,7 +180,7 @@ function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
           $links[$type] = array(
             '#theme' => 'menu_local_action',
             '#link' => array(
-              'title' => t('Add new @node_type', array('@node_type' => node_type_get_name($type))),
+              'title' => t('Add new @node_type', array('@node_type' => node_type_get_label($type))),
               'href' => 'node/add/' . $type . '/' . $forum_term->tid,
             ),
           );
diff --git a/core/modules/node/lib/Drupal/node/NodeFormController.php b/core/modules/node/lib/Drupal/node/NodeFormController.php
index b27e1a6..70e3c51 100644
--- a/core/modules/node/lib/Drupal/node/NodeFormController.php
+++ b/core/modules/node/lib/Drupal/node/NodeFormController.php
@@ -88,8 +88,8 @@ public function form(array $form, array &$form_state, EntityInterface $node) {
     // because hook_form() needs to be able to receive $form_state by reference.
     // @todo hook_form() implementations are unable to add #validate or #submit
     //   handlers to the form buttons below. Remove hook_form() entirely.
-    $function = node_type_get_base($node) . '_form';
-    if (function_exists($function) && ($extra = $function($node, $form_state))) {
+    $function = node_hook($node->type, 'form');
+    if ($function && ($extra = $function($node, $form_state))) {
       $form = array_merge_recursive($form, $extra);
     }
     // If the node type has a title, and the node type form defined no special
@@ -295,8 +295,7 @@ public function validate(array $form, array &$form_state) {
     // hook_node_validate() for miscellaneous validation needed by modules.
     // Can't use node_invoke() or module_invoke_all(), because $form_state must
     // be receivable by reference.
-    $function = node_type_get_base($node) . '_validate';
-    if (function_exists($function)) {
+    if ($function = node_hook($node->type, 'validate')) {
       $function($node, $form, $form_state);
     }
     foreach (module_implements('node_validate') as $module) {
@@ -384,7 +383,7 @@ public function save(array $form, array &$form_state) {
     $node->save();
     $node_link = l(t('view'), 'node/' . $node->nid);
     $watchdog_args = array('@type' => $node->type, '%title' => $node->label());
-    $t_args = array('@type' => node_type_get_name($node), '%title' => $node->label());
+    $t_args = array('@type' => node_get_type_label($node), '%title' => $node->label());
 
     if ($insert) {
       watchdog('content', '@type: added %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
diff --git a/core/modules/node/lib/Drupal/node/NodeStorageController.php b/core/modules/node/lib/Drupal/node/NodeStorageController.php
index 1b1eedd..1380cd7 100644
--- a/core/modules/node/lib/Drupal/node/NodeStorageController.php
+++ b/core/modules/node/lib/Drupal/node/NodeStorageController.php
@@ -176,8 +176,9 @@ protected function attachLoad(&$nodes, $load_revision = FALSE) {
 
     // Call object type specific callbacks on each typed array of nodes.
     foreach ($typed_nodes as $node_type => $nodes_of_type) {
-      if (node_hook($node_type, 'load')) {
-        $function = node_type_get_base($node_type) . '_load';
+      // Retrieve the node type 'base' hook implementation based on a Node in
+      // the type-specific stack.
+      if ($function = node_hook($node_type, 'load')) {
         $function($nodes_of_type);
       }
     }
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
index bf925c4..391e614 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTypeTest.php
@@ -42,7 +42,7 @@ function testNodeTypeGetFunctions() {
     $this->assertEqual($node_types['article']->name, $node_names['article'], t('Correct node type base has been returned.'));
 
     $this->assertEqual($node_types['article'], node_type_load('article'), t('Correct node type has been returned.'));
-    $this->assertEqual($node_types['article']->name, node_type_get_name('article'), t('Correct node type name has been returned.'));
+    $this->assertEqual($node_types['article']->name, node_type_get_label('article'), t('Correct node type name has been returned.'));
     $this->assertEqual($node_types['page']->base, node_type_get_base('page'), t('Correct node type base has been returned.'));
   }
 
diff --git a/core/modules/node/node.admin.inc b/core/modules/node/node.admin.inc
index 5cbe4ef..db113f5 100644
--- a/core/modules/node/node.admin.inc
+++ b/core/modules/node/node.admin.inc
@@ -492,7 +492,7 @@ function node_admin_nodes() {
           '#suffix' => ' ' . theme('mark', array('type' => node_mark($node->nid, $node->changed))),
         ),
       ),
-      'type' => check_plain(node_type_get_name($node)),
+      'type' => check_plain(node_get_type_label($node)),
       'author' => theme('username', array('account' => $node)),
       'status' => $node->status ? t('published') : t('not published'),
       'changed' => format_date($node->changed, 'short'),
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 7add837..f13403b 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -131,7 +131,7 @@ function node_help($path, $arg) {
 
     case 'admin/structure/types/manage/%/display':
       return '<p>' . t('Content items can be displayed using different view modes: Teaser, Full content, Print, RSS, etc. <em>Teaser</em> is a short format that is typically used in lists of multiple content items. <em>Full content</em> is typically used when the content is displayed on its own page.') . '</p>' .
-        '<p>' . t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', array('%type' => node_type_get_name($arg[4]))) . '</p>';
+        '<p>' . t('Here, you can define which fields are shown and hidden when %type content is displayed in each view mode, and define how the fields are displayed in each view mode.', array('%type' => node_type_get_label($arg[4]))) . '</p>';
 
     case 'node/%/revisions':
       return '<p>' . t('Revisions allow you to track differences between multiple versions of your content, and revert back to older versions.') . '</p>';
@@ -402,19 +402,6 @@ function node_mark($nid, $timestamp) {
 }
 
 /**
- * Extracts the type name.
- *
- * @param Drupal\node\Node|string $node
- *   Either a string or object, containing the node type information.
- *
- * @return
- *   Node type of the passed-in data.
- */
-function _node_extract_type($node) {
-  return is_object($node) ? $node->type : $node;
-}
-
-/**
  * Returns a list of all the available node types.
  *
  * This list can include types that are queued for addition or deletion.
@@ -436,16 +423,15 @@ function node_type_get_types() {
  * execute node-type-specific hooks. For types defined in the user interface
  * and managed by node.module, the base is 'node_content'.
  *
- * @param Drupal\node\Node|string $node
- *   A node entity or string that indicates the node type to return.
+ * @param string $type
+ *   A string that indicates the node type to return.
  *
- * @return
+ * @return string|false
  *   The node type base or FALSE if the node type is not found.
  *
  * @see node_invoke()
  */
-function node_type_get_base($node) {
-  $type = _node_extract_type($node);
+function node_type_get_base($type) {
   $types = _node_types_build()->types;
   return isset($types[$type]) && isset($types[$type]->base) ? $types[$type]->base : FALSE;
 }
@@ -457,25 +443,38 @@ function node_type_get_base($node) {
  * See _node_types_build() for details.
  *
  * @return
- *   An array of node type names, keyed by the type.
+ *   An array of node type labels, keyed by the node type name.
  */
 function node_type_get_names() {
   return _node_types_build()->names;
 }
 
 /**
- * Returns the node type name of the passed node or node type string.
+ * Returns the node type label for the passed node type name.
  *
- * @param Drupal\node\Node|string $node
- *   A node entity or string that indicates the node type to return.
+ * @param string $name
+ *   The machine name of a node type.
  *
- * @return
- *   The node type name or FALSE if the node type is not found.
+ * @return string|false
+ *   The node type label or FALSE if the node type is not found.
+ */
+function node_type_get_label($name) {
+  $types = _node_types_build()->names;
+  return isset($types[$name]) ? $types[$name] : FALSE;
+}
+
+/**
+ * Returns the node type label for the passed node.
+ *
+ * @param Drupal\node\Node $node
+ *   A node entity to return the node type's label for.
+ *
+ * @return string|false
+ *   The node type label or FALSE if the node type is not found.
  */
-function node_type_get_name($node) {
-  $type = _node_extract_type($node);
+function node_get_type_label($node) {
   $types = _node_types_build()->names;
-  return isset($types[$type]) ? $types[$type] : FALSE;
+  return isset($types[$node->type]) ? $types[$node->type] : FALSE;
 }
 
 /**
@@ -972,24 +971,24 @@ function node_rdf_mapping() {
 /**
  * Determines whether a node hook exists.
  *
- * @param Drupal\node\Node|string $node
- *   A node entity or a string containing the node type.
+ * @param string $type
+ *   A string containing the node type.
  * @param $hook
  *   A string containing the name of the hook.
  *
- * @return
- *   TRUE if the $hook exists in the node type of $node.
+ * @return string|false
+ *   A string containing the function name or FALSE if it isn't found.
  */
-function node_hook($node, $hook) {
-  $base = node_type_get_base($node);
-  return module_hook($base, $hook);
+function node_hook($type, $hook) {
+  $base = node_type_get_base($type);
+  return module_hook($base, $hook) ? $base . '_' . $hook : FALSE;
 }
 
 /**
  * Invokes a node hook.
  *
- * @param Drupal\node\Node|string $node
- *   A node entity or a string containing the node type.
+ * @param Drupal\node\Node $node
+ *   A Node entity.
  * @param $hook
  *   A string containing the name of the hook.
  * @param $a2, $a3, $a4
@@ -999,10 +998,8 @@ function node_hook($node, $hook) {
  *   The returned value of the invoked hook.
  */
 function node_invoke($node, $hook, $a2 = NULL, $a3 = NULL, $a4 = NULL) {
-  if (node_hook($node, $hook)) {
-    $base = node_type_get_base($node);
-    $function = $base . '_' . $hook;
-    return ($function($node, $a2, $a3, $a4));
+  if ($function = node_hook($node->type, $hook)) {
+    return $function($node, $a2, $a3, $a4);
   }
 }
 
@@ -1234,7 +1231,7 @@ function node_build_content(Node $node, $view_mode = 'full', $langcode = NULL) {
 
   // The 'view' hook can be implemented to overwrite the default function
   // to display nodes.
-  if (node_hook($node, 'view')) {
+  if (node_hook($node->type, 'view')) {
     $node = node_invoke($node, 'view', $view_mode, $langcode);
   }
 
@@ -1601,7 +1598,7 @@ function node_search_execute($keys = NULL, $conditions = NULL) {
     $uri = $node->uri();
     $results[] = array(
       'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE, 'language' => $language))),
-      'type' => check_plain(node_type_get_name($node)),
+      'type' => check_plain(node_get_type_label($node)),
       'title' => $node->label($item->langcode),
       'user' => theme('username', array('account' => $node)),
       'date' => $node->get('changed', $item->langcode),
@@ -3708,7 +3705,7 @@ function node_action_info() {
  */
 function node_publish_action(Node $node, $context = array()) {
   $node->status = NODE_PUBLISHED;
-  watchdog('action', 'Set @type %title to published.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Set @type %title to published.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3724,7 +3721,7 @@ function node_publish_action(Node $node, $context = array()) {
  */
 function node_unpublish_action(Node $node, $context = array()) {
   $node->status = NODE_NOT_PUBLISHED;
-  watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3740,7 +3737,7 @@ function node_unpublish_action(Node $node, $context = array()) {
  */
 function node_make_sticky_action(Node $node, $context = array()) {
   $node->sticky = NODE_STICKY;
-  watchdog('action', 'Set @type %title to sticky.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Set @type %title to sticky.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3756,7 +3753,7 @@ function node_make_sticky_action(Node $node, $context = array()) {
  */
 function node_make_unsticky_action(Node $node, $context = array()) {
   $node->sticky = NODE_NOT_STICKY;
-  watchdog('action', 'Set @type %title to unsticky.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Set @type %title to unsticky.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3772,7 +3769,7 @@ function node_make_unsticky_action(Node $node, $context = array()) {
  */
 function node_promote_action(Node $node, $context = array()) {
   $node->promote = NODE_PROMOTED;
-  watchdog('action', 'Promoted @type %title to front page.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Promoted @type %title to front page.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3788,7 +3785,7 @@ function node_promote_action(Node $node, $context = array()) {
  */
 function node_unpromote_action(Node $node, $context = array()) {
   $node->promote = NODE_NOT_PROMOTED;
-  watchdog('action', 'Removed @type %title from front page.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Removed @type %title from front page.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3801,7 +3798,7 @@ function node_unpromote_action(Node $node, $context = array()) {
  */
 function node_save_action(Node $node) {
   $node->save();
-  watchdog('action', 'Saved @type %title', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+  watchdog('action', 'Saved @type %title', array('@type' => node_get_type_label($node), '%title' => $node->label()));
 }
 
 /**
@@ -3822,7 +3819,7 @@ function node_save_action(Node $node) {
 function node_assign_owner_action(Node $node, $context) {
   $node->uid = $context['owner_uid'];
   $owner_name = db_query("SELECT name FROM {users} WHERE uid = :uid", array(':uid' => $context['owner_uid']))->fetchField();
-  watchdog('action', 'Changed owner of @type %title to uid %name.', array('@type' =>  node_type_get_name($node), '%title' => $node->label(), '%name' => $owner_name));
+  watchdog('action', 'Changed owner of @type %title to uid %name.', array('@type' =>  node_get_type_label($node), '%title' => $node->label(), '%name' => $owner_name));
 }
 
 /**
@@ -3938,7 +3935,7 @@ function node_unpublish_by_keyword_action(Node $node, $context) {
     $elements = node_view(clone $node);
     if (strpos(drupal_render($elements), $keyword) !== FALSE || strpos($node->label(), $keyword) !== FALSE) {
       $node->status = NODE_NOT_PUBLISHED;
-      watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_type_get_name($node), '%title' => $node->label()));
+      watchdog('action', 'Set @type %title to unpublished.', array('@type' => node_get_type_label($node), '%title' => $node->label()));
       break;
     }
   }
diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc
index b2d6a61..12437e1 100644
--- a/core/modules/node/node.pages.inc
+++ b/core/modules/node/node.pages.inc
@@ -17,8 +17,7 @@
  * @see node_menu()
  */
 function node_page_edit($node) {
-  $type_name = node_type_get_name($node);
-  drupal_set_title(t('<em>Edit @type</em> @title', array('@type' => $type_name, '@title' => $node->label())), PASS_THROUGH);
+  drupal_set_title(t('<em>Edit @type</em> @title', array('@type' => node_get_type_label($node), '@title' => $node->label())), PASS_THROUGH);
   return entity_get_form($node);
 }
 
@@ -210,7 +209,7 @@ function node_delete_confirm_submit($form, &$form_state) {
     $node = node_load($form_state['values']['nid']);
     node_delete($form_state['values']['nid']);
     watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->label()));
-    drupal_set_message(t('@type %title has been deleted.', array('@type' => node_type_get_name($node), '%title' => $node->label())));
+    drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_type_label($node), '%title' => $node->label())));
   }
 
   $form_state['redirect'] = '<front>';
@@ -303,7 +302,7 @@ function node_revision_revert_confirm_submit($form, &$form_state) {
   $node_revision->save();
 
   watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->label(), '%revision' => $node_revision->vid));
-  drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_type_get_name($node_revision), '%title' => $node_revision->label(), '%revision-date' => format_date($original_revision_timestamp))));
+  drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_type_label($node_revision), '%title' => $node_revision->label(), '%revision-date' => format_date($original_revision_timestamp))));
   $form_state['redirect'] = 'node/' . $node_revision->nid . '/revisions';
 }
 
@@ -328,7 +327,7 @@ function node_revision_delete_confirm_submit($form, &$form_state) {
   node_revision_delete($node_revision->vid);
 
   watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->label(), '%revision' => $node_revision->vid));
-  drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_type_get_name($node_revision), '%title' => $node_revision->label())));
+  drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_type_label($node_revision), '%title' => $node_revision->label())));
   $form_state['redirect'] = 'node/' . $node_revision->nid;
   if (db_query('SELECT COUNT(vid) FROM {node_revision} WHERE nid = :nid', array(':nid' => $node_revision->nid))->fetchField() > 1) {
     $form_state['redirect'] .= '/revisions';
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index ce44ffe..0bd1000 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -125,7 +125,7 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
           break;
 
         case 'type-name':
-          $type_name = node_type_get_name($node);
+          $type_name = node_get_type_label($node);
           $replacements[$original] = $sanitize ? check_plain($type_name) : $type_name;
           break;
 
diff --git a/core/modules/poll/lib/Drupal/poll/Tests/PollTestBase.php b/core/modules/poll/lib/Drupal/poll/Tests/PollTestBase.php
index cd519b8..7410313 100644
--- a/core/modules/poll/lib/Drupal/poll/Tests/PollTestBase.php
+++ b/core/modules/poll/lib/Drupal/poll/Tests/PollTestBase.php
@@ -74,7 +74,7 @@ function pollCreate($title, $choices, $preview = TRUE) {
 
     $this->drupalPost(NULL, $edit, t('Save'));
     $node = $this->drupalGetNodeByTitle($title);
-    $this->assertText(t('@type @title has been created.', array('@type' => node_type_get_name('poll'), '@title' => $title)), 'Poll has been created.');
+    $this->assertText(t('@type @title has been created.', array('@type' => node_type_get_label('poll'), '@title' => $title)), 'Poll has been created.');
     $this->assertTrue($node->nid, t('Poll has been found in the database.'));
 
     return isset($node->nid) ? $node->nid : FALSE;
@@ -188,6 +188,6 @@ function assertPollChoiceOrder(array $choices, $index = 0, $preview = FALSE) {
   function pollUpdate($nid, $title, $edit) {
     // Edit the poll node.
     $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save'));
-    $this->assertText(t('@type @title has been updated.', array('@type' => node_type_get_name('poll'), '@title' => $title)), 'Poll has been updated.');
+    $this->assertText(t('@type @title has been updated.', array('@type' => node_type_get_label('poll'), '@title' => $title)), 'Poll has been updated.');
   }
 }
diff --git a/core/modules/search/search.api.php b/core/modules/search/search.api.php
index 295c5ea..3dcea0d 100644
--- a/core/modules/search/search.api.php
+++ b/core/modules/search/search.api.php
@@ -239,7 +239,7 @@ function hook_search_execute($keys = NULL, $conditions = NULL) {
     $uri = $node->uri();
     $results[] = array(
       'link' => url($uri['path'], array_merge($uri['options'], array('absolute' => TRUE, 'language' => $language))),
-      'type' => check_plain(node_type_get_name($node)),
+      'type' => check_plain(node_get_type_label($node)),
       'title' => $node->label($item->langcode),
       'user' => theme('username', array('account' => $node)),
       'date' => $node->get('changed', $item->langcode),
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 14f3630..d9556a7 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -2003,7 +2003,7 @@ function hook_mail($key, &$message, $params) {
     $variables += array(
       '%uid' => $node->uid,
       '%node_url' => url('node/' . $node->nid, array('absolute' => TRUE)),
-      '%node_type' => node_type_get_name($node),
+      '%node_type' => node_get_type_label($node),
       '%title' => $node->title,
       '%teaser' => $node->teaser,
       '%body' => $node->body,
diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc
index f012264..853f50d 100644
--- a/core/modules/tracker/tracker.pages.inc
+++ b/core/modules/tracker/tracker.pages.inc
@@ -70,7 +70,7 @@ function tracker_page($account = NULL, $set_title = FALSE) {
       }
 
       $row = array(
-        'type' => check_plain(node_type_get_name($node->type)),
+        'type' => check_plain(node_get_type_label($node)),
         // Do not use $node->label(), because $node comes from the database.
         'title' => array('data' => l($node->title, 'node/' . $node->nid) . ' ' . theme('mark', array('type' => node_mark($node->nid, $node->changed)))),
         'author' => array('data' => theme('username', array('account' => $node))),
