diff --git src/wp-includes/nav-menu.php src/wp-includes/nav-menu.php
index 6ce589b..166c30c 100644
--- src/wp-includes/nav-menu.php
+++ src/wp-includes/nav-menu.php
@@ -564,6 +564,10 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item
 		wp_update_post( $post );
 	}
 
+	// Invalidate wp_get_nav_menu_items object cache
+	$cache_key = sprintf( 'menu_items:%s:%s', $menu_id, md5( serialize( $args ) ) );
+	wp_cache_delete( $cache_key, 'menu' );
+
 	/**
 	 * Fires after a navigation menu item has been updated.
 	 *
@@ -684,7 +688,16 @@ function wp_get_nav_menu_items( $menu, $args = array() ) {
 	$args['include'] = $items;
 
 	if ( ! empty( $items ) ) {
-		$items = get_posts( $args );
+		$cache_key = sprintf( 'menu_items:%s:%s', $menu->ID, md5( serialize( $args ) ) );
+		if ( false === ( $item_ids = wp_cache_get( $cache_key, 'menu' ) ) ) {
+			$item_ids = array();
+			foreach ( get_posts( $args ) as $post ) {
+				$item_ids []= $post->ID;
+			}
+			wp_cache_set( $cache_key, $item_ids, 'menu' );
+		}
+
+		$items = array_filter( array_map( 'get_post', $item_ids ), 'is_post' );
 	} else {
 		$items = array();
 	}
diff --git tests/phpunit/tests/post/nav-menu.php tests/phpunit/tests/post/nav-menu.php
index d99b1a9..52b9268 100644
--- tests/phpunit/tests/post/nav-menu.php
+++ tests/phpunit/tests/post/nav-menu.php
@@ -505,6 +505,81 @@ class Test_Nav_Menus extends WP_UnitTestCase {
 	}
 
 	/**
+	 * @ticket 27120
+	 */
+	function test_nav_menu_cache() {
+		$post_id = self::factory()->post->create();
+
+		wp_update_nav_menu_item(
+			$this->menu_id, 0, array(
+				'menu-item-type'      => 'post_type',
+				'menu-item-object'    => 'post',
+				'menu-item-object-id' => $post_id,
+				'menu-item-status'    => 'publish',
+			)
+		);
+
+		global $wpdb;
+
+		$num_queries = $wpdb->num_queries;
+
+		/** First call */
+		$menu = wp_nav_menu(
+			array(
+				'echo' => false,
+				'menu' => $this->menu_id,
+			)
+		);
+
+		$this->assertNotEquals( $num_queries, $wpdb->num_queries );
+
+		$num_queries = $wpdb->num_queries;
+
+		/** Cached call */
+		$menu = wp_nav_menu(
+			array(
+				'echo' => false,
+				'menu' => $this->menu_id,
+			)
+		);
+
+		$this->assertEquals( $num_queries, $wpdb->num_queries );
+
+		$post_id = self::factory()->post->create();
+
+		$new_item_id = wp_update_nav_menu_item(
+			$this->menu_id, 0, array(
+				'menu-item-type'      => 'post_type',
+				'menu-item-object'    => 'post',
+				'menu-item-object-id' => $post_id,
+				'menu-item-status'    => 'publish',
+			)
+		);
+
+		/** Invalidated */
+		$menu = wp_nav_menu(
+			array(
+				'echo' => false,
+				'menu' => $this->menu_id,
+			)
+		);
+
+		$this->assertContains( "menu-item-$new_item_id", $menu );
+
+		/** Delete invalidated */
+		wp_delete_post( $post_id );
+
+		$menu = wp_nav_menu(
+			array(
+				'echo' => false,
+				'menu' => $this->menu_id,
+			)
+		);
+
+		$this->assertNotContains( "menu-item-$new_item_id", $menu );
+	}
+
+	/**
 	 * Run tests required to confrim Walker_Nav_Menu receives an $args object.
 	 */
 	function _confirm_nav_menu_item_args_object( $args ) {
