diff --git a/core/modules/hal/hal.services.yml b/core/modules/hal/hal.services.yml
index 7f3e405..e69694b 100644
--- a/core/modules/hal/hal.services.yml
+++ b/core/modules/hal/hal.services.yml
@@ -24,6 +24,12 @@ services:
       - { name: normalizer, priority: 10 }
     calls:
       - [setLinkManager, ['@rest.link_manager']]
+  serializer.normalizer.entity_collection.hal:
+    class: Drupal\hal\Normalizer\EntityCollectionNormalizer
+    tags:
+      - { name: normalizer, priority: 10 }
+    calls:
+      - [setLinkManager, ['@rest.link_manager']]
   serializer.encoder.hal:
     class: Drupal\hal\Encoder\JsonEncoder
     tags:
diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityCollectionNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityCollectionNormalizer.php
new file mode 100644
index 0000000..7f06eb4
--- /dev/null
+++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityCollectionNormalizer.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\hal\Normalizer\EntityNormalizer.
+ */
+
+namespace Drupal\hal\Normalizer;
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\Language\Language;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
+
+/**
+ * Converts the Drupal entity object structure to a HAL array structure.
+ */
+class EntityCollectionNormalizer extends NormalizerBase {
+
+  /**
+   * The interface or class that this Normalizer supports.
+   *
+   * @var string
+   */
+  protected $supportedInterfaceOrClass = 'Drupal\serialization\EntityCollection';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function normalize($object, $format = NULL, array $context = array()) {
+    // Create the array of normalized properties, starting with the URI.
+    $normalized = array(
+      '_links' => array(
+        'self' => array(
+          'href' => $object->getUri(),
+        ),
+      ),
+    );
+
+    // Add the list of items.
+    $link_relation = $this->linkManager->getCollectionItemRelation($object->getCollectionId());
+    $normalized['_embedded'][$link_relation] = $this->serializer->normalize($object->getItems(), $format, $context);
+
+    return $normalized;
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
+   *
+   * @todo Implement denormalization once normalization has settled.
+   */
+  public function denormalize($data, $class, $format = NULL, array $context = array()) {
+  }
+}
diff --git a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
index 414a284..0f1dcc0 100644
--- a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
+++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php
@@ -15,6 +15,7 @@
 use Drupal\hal\Normalizer\FieldItemNormalizer;
 use Drupal\hal\Normalizer\FieldNormalizer;
 use Drupal\rest\LinkManager\LinkManager;
+use Drupal\rest\LinkManager\CollectionLinkManager;
 use Drupal\rest\LinkManager\RelationLinkManager;
 use Drupal\rest\LinkManager\TypeLinkManager;
 use Drupal\simpletest\DrupalUnitTestBase;
@@ -125,7 +126,7 @@ function setUp() {
       new FieldItemNormalizer(),
       new FieldNormalizer(),
     );
-    $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('cache')), new RelationLinkManager(new MemoryBackend('cache')));
+    $link_manager = new LinkManager(new TypeLinkManager(new MemoryBackend('cache')), new RelationLinkManager(new MemoryBackend('cache')), new CollectionLinkManager());
     foreach ($normalizers as $normalizer) {
       $normalizer->setLinkManager($link_manager);
     }
diff --git a/core/modules/hal/tests/EntityCollectionNormalizerTest.php b/core/modules/hal/tests/EntityCollectionNormalizerTest.php
new file mode 100644
index 0000000..e65f622
--- /dev/null
+++ b/core/modules/hal/tests/EntityCollectionNormalizerTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Contains \Drupal\hal\Tests\EntityCollectionNormalizerTest.
+ */
+
+namespace Drupal\hal\Tests;
+
+use Drupal\hal\Normalizer\EntityCollectionNormalizer;
+use Drupal\serialization\EntityCollection;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the EntityCollectionNormalizer's normalize support.
+ *
+ * @group HAL
+ */
+class EntityCollectionNormalizerTest extends UnitTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'EntityCollectionNormalizer test',
+      'description' => "Unit test of the EntityCollectionNormalizer's normalize support.",
+      'group' => 'HAL',
+    );
+  }
+
+  /**
+   * Tests the supportsNormalization method.
+   */
+  public function testSupportsNormalization() {
+    $collection = $this->getEntityCollection();
+    $normalizer = new EntityCollectionNormalizer();
+    $this->assertTrue($normalizer->supportsNormalization($collection, 'hal_json'));
+    $this->assertFalse($normalizer->supportsNormalization($collection, 'json'));
+    $this->assertFalse($normalizer->supportsNormalization(new \stdClass(), 'hal_json'));
+  }
+
+  /**
+   * Tests the normalize method.
+   */
+  public function testNormalize() {
+    $test_values = $this->getTestValues();
+    $collection = $this->getEntityCollection();
+
+    // Create the normalizer and inject the LinkManagerStub.
+    $normalizer = new EntityCollectionNormalizer();
+    $normalizer->setLinkManager($this->getLinkManagerStub());
+    // Inject the Serializer. Handle the call to Serializer::normalize,
+    // ensuring that the items array is passed in.
+    $serializer = $this->getSerializerStub();
+    $serializer->expects($this->any())
+      ->method('normalize')
+      ->with($collection->getItems())
+      ->will($this->returnValue($test_values['items']));
+    $normalizer->setSerializer($serializer);
+    // Get the normalized array.
+    $normalized = $normalizer->normalize($collection, 'hal_json');
+
+    // Test that self link points to collection URI.
+    $this->assertEquals($normalized['_links']['self']['href'], $test_values['uri']);
+    // Test that the correct link relation was retrieved from the LinkManager
+    // and added to _embedded.
+    $this->assertArrayHasKey($test_values['item_link_relation'], $normalized['_embedded']);
+    // Test that the item link relation points to the serialized item array.
+    $this->assertEquals($normalized['_embedded'][$test_values['item_link_relation']], $test_values['items']);
+  }
+
+  /**
+   * Get an EntityCollection for testing.
+   *
+   * @return \Drupal\serialization\EntityCollection
+   *   The EntityCollection object, configured with test values.
+   */
+  protected function getEntityCollection() {
+    $test_values = $this->getTestValues();
+
+    // Get a dummy node.
+    $node = $this->getMockBuilder('Drupal\node\Entity\Node')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $collection = new EntityCollection('test_id');
+    $collection->setUri($test_values['uri']);
+    $collection->setItems(array($node));
+
+    return $collection;
+  }
+
+  /**
+   * Get a stub LinkManager for testing.
+   *
+   * @return \PHPUnit_Framework_MockObject_MockObject
+   *   The LinkManager stub.
+   */
+  protected function getLinkManagerStub() {
+    $test_values = $this->getTestValues();
+
+    $link_manager = $this->getMockBuilder('Drupal\rest\LinkManager\LinkManager')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $link_manager->expects($this->any())
+      ->method('getCollectionItemRelation')
+      ->will($this->returnValue($test_values['item_link_relation']));
+
+    return $link_manager;
+  }
+
+  /**
+   * Get a stub Serializer for testing.
+   *
+   * @return \PHPUnit_Framework_MockObject_MockObject
+   *   The Serializer stub.
+   */
+  protected function getSerializerStub() {
+    $serializer = $this->getMockBuilder('Symfony\Component\Serializer\Serializer')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    return $serializer;
+  }
+
+  /**
+   * Get the array of test values.
+   *
+   * @return array
+   *   An array of test values, used for configuring stub methods and testing.
+   */
+  protected function getTestValues() {
+    return array(
+      'item_link_relation' => 'item',
+      'items' => 'Array of serialized entities goes here',
+      'uri' => 'http://example.com/test-path',
+    );
+  }
+}
diff --git a/core/modules/rest/lib/Drupal/rest/LinkManager/CollectionLinkManager.php b/core/modules/rest/lib/Drupal/rest/LinkManager/CollectionLinkManager.php
new file mode 100644
index 0000000..3097f3b
--- /dev/null
+++ b/core/modules/rest/lib/Drupal/rest/LinkManager/CollectionLinkManager.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * Contains \Drupal\rest\LinkManager\CollectionLinkManager.
+ */
+
+namespace Drupal\rest\LinkManager;
+
+/**
+ * Default collection link relation mapper.
+ */
+class CollectionLinkManager implements CollectionLinkManagerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCollectionItemRelation($collection_id) {
+    // By default, use the item IANA Link Relation, which is a generic way to
+    // link to items from a collection. See http://tools.ietf.org/html/rfc6573.
+    return 'item';
+  }
+
+}
diff --git a/core/modules/rest/lib/Drupal/rest/LinkManager/CollectionLinkManagerInterface.php b/core/modules/rest/lib/Drupal/rest/LinkManager/CollectionLinkManagerInterface.php
new file mode 100644
index 0000000..42623bb
--- /dev/null
+++ b/core/modules/rest/lib/Drupal/rest/LinkManager/CollectionLinkManagerInterface.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Contains \Drupal\rest\LinkManager\CollectionLinkManagerInterface.
+ */
+
+namespace Drupal\rest\LinkManager;
+
+/**
+ * Interface for mapping collection (e.g. Views) link relations.
+ */
+interface CollectionLinkManagerInterface {
+
+  /**
+   * Get link relating collection to item.
+   *
+   * @param string $collection_id
+   *   The identifier of a collection (e.g. View name).
+   *
+   * @return string
+   *   The link relation.
+   */
+  public function getCollectionItemRelation($collection_id);
+}
diff --git a/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManager.php b/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManager.php
index 742fcfd..386077f 100644
--- a/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManager.php
+++ b/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManager.php
@@ -23,16 +23,26 @@ class LinkManager implements LinkManagerInterface {
   protected $relationLinkManager;
 
   /**
+   * The collection link manager.
+   *
+   * @var \Drupal\rest\LinkManager\CollectionLinkManagerInterface
+   */
+  protected $collectionLinkManager;
+
+  /**
    * Constructor.
    *
    * @param \Drupal\rest\LinkManager\TypeLinkManagerInterface $type_link_manager
-   *   Manager for handling bundle URIs.
+   *   Manager for handling type links corresponding to bundles.
    * @param \Drupal\rest\LinkManager\RelationLinkManagerInterface $relation_link_manager
-   *   Manager for handling bundle URIs.
+   *   Manager for handling link relations corresponding to fields.
+   * @param \Drupal\rest\LinkManager\CollectionLinkManagerInterface $collection_link_manager
+   *   Manager for handling collection links.
    */
-  public function __construct(TypeLinkManagerInterface $type_link_manager, RelationLinkManagerInterface $relation_link_manager) {
+  public function __construct(TypeLinkManagerInterface $type_link_manager, RelationLinkManagerInterface $relation_link_manager, CollectionLinkManagerInterface $collection_link_manager) {
     $this->typeLinkManager = $type_link_manager;
     $this->relationLinkManager = $relation_link_manager;
+    $this->collectionLinkManager = $collection_link_manager;
   }
 
   /**
@@ -62,4 +72,11 @@ public function getRelationUri($entity_type, $bundle, $field_name) {
   public function getRelationInternalIds($relation_uri) {
     return $this->relationLinkManager->getRelationInternalIds($relation_uri);
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCollectionItemRelation($collection_id) {
+    return $this->collectionLinkManager->getCollectionItemRelation($collection_id);
+  }
 }
diff --git a/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManagerInterface.php b/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManagerInterface.php
index 60e5629..c9fd834 100644
--- a/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManagerInterface.php
+++ b/core/modules/rest/lib/Drupal/rest/LinkManager/LinkManagerInterface.php
@@ -16,8 +16,8 @@
  * extending all of the component ones.
  *
  * While a link manager may directly implement these interface methods with
- * custom logic, it is expected to be more common for plugin managers to proxy
+ * custom logic, it is expected to be more common for link managers to proxy
  * the method invocations to the respective components.
  */
-interface LinkManagerInterface extends TypeLinkManagerInterface, RelationLinkManagerInterface {
+interface LinkManagerInterface extends TypeLinkManagerInterface, RelationLinkManagerInterface, CollectionLinkManagerInterface {
 }
diff --git a/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php b/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php
index 605006a..111d2dd 100644
--- a/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php
+++ b/core/modules/rest/lib/Drupal/rest/Plugin/views/style/Serializer.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\rest\Plugin\views\style;
 
+use Drupal\serialization\EntityCollection;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\style\StylePluginBase;
@@ -115,17 +116,7 @@ public function submitOptionsForm(&$form, &$form_state) {
    * {@inheritdoc}
    */
   public function render() {
-    $rows = array();
-    // If the Data Entity row plugin is used, this will be an array of entities
-    // which will pass through Serializer to one of the registered Normalizers,
-    // which will transform it to arrays/scalars. If the Data field row plugin
-    // is used, $rows will not contain objects and will pass directly to the
-    // Encoder.
-    foreach ($this->view->result as $row) {
-      $rows[] = $this->view->rowPlugin->render($row);
-    }
-
-    return $this->serializer->serialize($rows, $this->displayHandler->getContentType());
+    return $this->serializer->serialize($this->getEntityCollection(), $this->displayHandler->getContentType());
   }
 
   /**
@@ -145,4 +136,27 @@ public function getFormats() {
     return $this->formats;
   }
 
+  /**
+   * Build the Entity Collection object for a set of view results.
+   *
+   * @return \Drupal\serialization\EntityCollection
+   *   The collection object to pass into the serializer.
+   */
+  protected function getEntityCollection() {
+    // @todo Determine how to handle field-based views.
+    foreach ($this->view->result as $row) {
+      $rows[] = $this->view->rowPlugin->render($row);
+    }
+
+    // @todo Use real view name.
+    $collection = new EntityCollection('view_name');
+    $collection->setTitle($this->view->getTitle());
+    // @todo Use the real description.
+    $collection->setDescription('foobar');
+    $uri = url($this->view->getUrl(), array('absolute' => TRUE));
+    $collection->setUri($uri);
+    $collection->setItems($rows);
+
+    return $collection;
+  }
 }
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php b/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php
index 6594cfd..f2c8e04 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/Views/StyleSerializerTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\rest\Tests\Views;
 
+use Drupal\serialization\EntityCollection;
 use Drupal\views\Tests\Plugin\PluginTestBase;
 use Drupal\views\Tests\ViewTestData;
 
@@ -110,19 +111,15 @@ public function testSerializerResponses() {
 
     // Get the serializer service.
     $serializer = $this->container->get('serializer');
-
-    $entities = array();
-    foreach ($view->result as $row) {
-      $entities[] = $row->_entity;
-    }
-
-    $expected = $serializer->serialize($entities, 'json');
+    // Create the entity collection.
+    $collection = $this->getEntityCollection($view);
+    $expected = $serializer->serialize($collection, 'json');
 
     $actual_json = $this->drupalGet('test/serialize/entity', array(), array('Accept: application/json'));
     $this->assertResponse(200);
     $this->assertIdentical($actual_json, $expected, 'The expected JSON output was found.');
 
-    $expected = $serializer->serialize($entities, 'hal_json');
+    $expected = $serializer->serialize($collection, 'hal_json');
     $actual_json = $this->drupalGet('test/serialize/entity', array(), array('Accept: application/hal+json'));
     $this->assertIdentical($actual_json, $expected, 'The expected HAL output was found.');
   }
@@ -273,13 +270,9 @@ public function testPreview() {
 
     // Get the serializer service.
     $serializer = $this->container->get('serializer');
-
-    $entities = array();
-    foreach ($view->result as $row) {
-      $entities[] = $row->_entity;
-    }
-
-    $expected = check_plain($serializer->serialize($entities, 'json'));
+    // Create the collection.
+    $collection = $this->getEntityCollection($view);
+    $expected = check_plain($serializer->serialize($collection, 'json'));
 
     $view->display_handler->setContentType('json');
     $view->live_preview = TRUE;
@@ -289,4 +282,27 @@ public function testPreview() {
     $this->assertEqual($rendered_json, $expected, 'Ensure the previewed json is escaped.');
   }
 
+  /**
+   * Build the Entity Collection object for a set of view results.
+   *
+   * @return \Drupal\serialization\EntityCollection
+   *   The collection object to pass into the serializer.
+   */
+  protected function getEntityCollection($view) {
+    foreach ($view->result as $row) {
+      $rows[] = $view->rowPlugin->render($row);
+    }
+
+    // @todo Use real view name.
+    $collection = new EntityCollection('view_name');
+    $collection->setTitle($view->getTitle());
+    // @todo Use the real description.
+    $collection->setDescription('foobar');
+    $uri = url($view->getUrl(), array('absolute' => TRUE));
+    $collection->setUri($uri);
+    $collection->setItems($rows);
+
+    return $collection;
+  }
+
 }
diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml
index d238442..16afb28 100644
--- a/core/modules/rest/rest.services.yml
+++ b/core/modules/rest/rest.services.yml
@@ -20,10 +20,12 @@ services:
       - { name: access_check }
   rest.link_manager:
     class: Drupal\rest\LinkManager\LinkManager
-    arguments: ['@rest.link_manager.type', '@rest.link_manager.relation']
+    arguments: ['@rest.link_manager.type', '@rest.link_manager.relation', '@rest.link_manager.collection']
   rest.link_manager.type:
     class: Drupal\rest\LinkManager\TypeLinkManager
     arguments: ['@cache.cache']
   rest.link_manager.relation:
     class: Drupal\rest\LinkManager\RelationLinkManager
     arguments: ['@cache.cache']
+  rest.link_manager.collection:
+    class: Drupal\rest\LinkManager\CollectionLinkManager
diff --git a/core/modules/serialization/lib/Drupal/serialization/EntityCollection.php b/core/modules/serialization/lib/Drupal/serialization/EntityCollection.php
new file mode 100644
index 0000000..5434b35
--- /dev/null
+++ b/core/modules/serialization/lib/Drupal/serialization/EntityCollection.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\serializationEntityCollection
+ */
+
+namespace Drupal\serialization;
+
+/**
+ * Provides a wrapper for a collection of entities, e.g. a feed channel.
+ */
+class EntityCollection implements \IteratorAggregate {
+
+  /**
+   * An internal identifier for this collection (e.g. view name).
+   *
+   * @var string
+   */
+  protected $id;
+
+  /**
+   * The entities in the collection.
+   *
+   * var array
+   */
+  protected $items;
+
+  /**
+   * The title of the collection.
+   *
+   * @var string
+   */
+  protected $title;
+
+  /**
+   * The URI of the channel.
+   *
+   * @var string
+   */
+  protected $uri;
+
+  /**
+   * The description of the channel.
+   *
+   * @var string
+   */
+  protected $description;
+
+  /**
+   * Constructor.
+   *
+   * @param string $collection_id
+   *   The internal identifier for the collection (e.g. view name).
+   */
+  public function __construct($collection_id) {
+    $this->id = $collection_id;
+  }
+
+  /**
+   * Get the internal ID of the collection.
+   */
+  public function getCollectionId() {
+    return $this->id;
+  }
+
+  /**
+   * Get the items list.
+   *
+   * @return array
+   */
+  public function getItems() {
+    return $this->items;
+  }
+
+  /**
+   * Set the items list.
+   *
+   * @param array $items
+   */
+  public function setItems($items) {
+    $this->items = $items;
+  }
+
+  /**
+   * Get the collection title.
+   *
+   * @return string
+   */
+  public function getTitle() {
+    return $this->title;
+  }
+
+  /**
+   * Set the collection title.
+   *
+   * @param string $title
+   */
+  public function setTitle($title) {
+    $this->title = $title;
+  }
+
+  /**
+   * Get the collection URI.
+   *
+   * @return string
+   */
+  public function getUri() {
+    return $this->uri;
+  }
+
+  /**
+   * Set the collection URI.
+   *
+   * @param string $uri
+   */
+  public function setUri($uri) {
+    $this->uri = $uri;
+  }
+
+  /**
+   * Get the collection description.
+   *
+   * @return string
+   */
+  public function getDescription() {
+    return $this->description;
+  }
+
+  /**
+   * Set the collection URI.
+   *
+   * @param string $description
+   */
+  public function setDescription($description) {
+    $this->description = $description;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIterator() {
+    return new \ArrayIterator($this->getItems());
+  }
+
+}
