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..05e5dfc
--- /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.
+    foreach ($object->getItems() as $item) {
+      $link_relation = $this->linkManager->getCollectionItemRelation($object->getCollectionId());
+      $normalized['_embedded'][$link_relation][] = $this->serializer->normalize($item, $format, $context);
+    }
+
+    return $normalized;
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
+   */
+  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/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());
+  }
+
+}
