diff --git a/recurring_events.info.yml b/recurring_events.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..088a9e9fc5d54b40f3b73db70711d4c69c9ef487
--- /dev/null
+++ b/recurring_events.info.yml
@@ -0,0 +1,5 @@
+name: 'Recurring Events'
+type: module
+description: 'Events and Registration Management Module'
+core: 8.x
+package: 'Recurring Events'
diff --git a/recurring_events.permissions.yml b/recurring_events.permissions.yml
new file mode 100644
index 0000000000000000000000000000000000000000..88013bd0a5f3ae8dfc27472fbdec1938a919c81d
--- /dev/null
+++ b/recurring_events.permissions.yml
@@ -0,0 +1,25 @@
+# Event Series Entities.
+add eventseries entity:
+  title: 'Add eventseries entity'
+  description: 'Create new event series entities'
+view eventseries entity:
+  title: 'View eventseries entity'
+  description: 'View existing event series entities'
+edit eventseries entity:
+  title: 'Edit eventseries entity'
+  description: 'Modify existing event series entities'
+delete eventseries entity:
+  title: 'Delete eventseries entity'
+  description: 'Delete existing event series entities'
+clone eventseries entity:
+  title: 'Clone eventseries entity'
+  description: 'Clone existing event series entities'
+
+# Event Series Administration.
+administer eventseries:
+  title: 'Administer eventseries'
+  description: 'Promote, change ownership, edit revisions, and perform other tasks for eventseries.'
+  restrict access: true
+access eventseries overview:
+  title: 'Access the eventseries overview page'
+  description: 'View the admin table view of eventseries'
\ No newline at end of file
diff --git a/recurring_events.routing.yml b/recurring_events.routing.yml
new file mode 100644
index 0000000000000000000000000000000000000000..27494745fe8e1bb3c1cbff0c051353f57b0cb8a2
--- /dev/null
+++ b/recurring_events.routing.yml
@@ -0,0 +1,55 @@
+# Add an EventSeries.
+entity.eventseries.add_form:
+  path: '/events/series/add'
+  defaults:
+  # Calls the form.add controller, defined in the event entity.
+    _entity_form: eventseries.add
+    _title: 'Add Event'
+  requirements:
+    _entity_create_access: 'eventseries'
+    _access_event: 'create'
+  options:
+    _admin_route: TRUE
+
+# Edit an EventSeries.
+entity.eventseries.edit_form:
+  path: '/events/series/{eventseries}/edit'
+  defaults:
+    _entity_form: eventseries.edit
+    _title: 'Edit Event Series'
+  requirements:
+    _entity_access: 'eventseries.edit'
+    _access_event: 'update'
+  options:
+    _admin_route: TRUE
+
+# Delete an EventSeries.
+entity.eventseries.delete_form:
+  path: '/events/series/{eventseries}/delete'
+  defaults:
+    _entity_form: eventseries.delete
+    _title: 'Delete Event'
+  requirements:
+    _entity_access: 'eventseries.delete'
+    _access_event: 'delete'
+  options:
+    _admin_route: TRUE
+
+# Clone an EventSeries.
+entity.eventseries.clone_form:
+  path: '/events/series/{eventseries}/clone'
+  defaults:
+    _entity_form: eventseries.clone
+    _title_callback: '\Drupal\recurring_events\Controller\EventSeriesController::getCloneTitle'
+  requirements:
+    _entity_access: 'eventseries.clone'
+    _access_event: 'clone'
+  options:
+    _admin_route: TRUE
+
+# Event Series table list route.
+entity.eventseries.collection:
+  path: '/admin/content/events/series'
+  requirements:
+  # Checks for permission directly.
+    _permission: 'access eventseries overview'
\ No newline at end of file
diff --git a/src/Entity/EventSeries.php b/src/Entity/EventSeries.php
index 0fb7333e665cc0002a50022ded02b68ea5d9aad0..12550e4cae53dac544737568d31b88195b71ac3e 100644
--- a/src/Entity/EventSeries.php
+++ b/src/Entity/EventSeries.php
@@ -401,7 +401,7 @@ class EventSeries extends EditorialContentEntityBase implements EventSeriesInter
       ->setLabel(t('Events in this Series'))
       ->setDescription(t('The events in this series.'))
       ->setRevisionable(FALSE)
-      ->setSetting('target_type', 'eventinstance')
+      ->setSetting('target_type', 'node')
       ->setTranslatable(FALSE)
       ->setDisplayOptions('view', [
         'label' => 'above',
diff --git a/src/EventSeriesAccessControlHandler.php b/src/EventSeriesAccessControlHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..d686a8ecf3f5427a4c52ac82d1b0cbe5e74dfc59
--- /dev/null
+++ b/src/EventSeriesAccessControlHandler.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\recurring_events;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\EntityAccessControlHandler;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Access controller for the eventseries entity.
+ *
+ * @see \Drupal\recurring_events\Entity\EventSeries.
+ */
+class EventSeriesAccessControlHandler extends EntityAccessControlHandler {
+
+  /**
+   * {@inheritdoc}
+   *
+   * Link the activities to the permissions. checkAccess is called with the
+   * $operation as defined in the routing.yml file.
+   */
+  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
+    switch ($operation) {
+      case 'view':
+        return AccessResult::allowedIfHasPermission($account, 'view eventseries entity');
+
+      case 'edit':
+        return AccessResult::allowedIfHasPermission($account, 'edit eventseries entity');
+
+      case 'delete':
+        return AccessResult::allowedIfHasPermission($account, 'delete eventseries entity');
+
+      case 'clone':
+        return AccessResult::allowedIfHasPermission($account, 'clone eventseries entity');
+    }
+    return AccessResult::allowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * Separate from the checkAccess because the entity does not yet exist, it
+   * will be created during the 'add' process.
+   */
+  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
+    return AccessResult::allowedIfHasPermission($account, 'add eventseries entity');
+  }
+
+}
diff --git a/src/Form/EventSeriesForm.php b/src/Form/EventSeriesForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..cbef12e7e040d78d10148808fbc3a0e49778fbd4
--- /dev/null
+++ b/src/Form/EventSeriesForm.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Drupal\recurring_events\Form;
+
+use Drupal\Core\Entity\ContentEntityForm;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Form controller for the eventseries entity edit forms.
+ *
+ * @ingroup recurring_events
+ */
+class EventSeriesForm extends ContentEntityForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildForm($form, $form_state);
+
+    /* @var $entity \Drupal\recurring_events\Entity\EventSeries */
+    $entity = $this->entity;
+
+    $form['advanced']['#attributes']['class'][] = 'entity-meta';
+
+    $form['meta'] = [
+      '#type' => 'details',
+      '#group' => 'advanced',
+      '#weight' => -10,
+      '#title' => $this->t('Status'),
+      '#attributes' => ['class' => ['entity-meta__header']],
+      '#tree' => TRUE,
+      '#access' => \Drupal::currentUser()->hasPermission('administer eventseries'),
+    ];
+    $form['meta']['published'] = [
+      '#type' => 'item',
+      '#markup' => $entity->isPublished() ? $this->t('Published') : $this->t('Not published'),
+      '#access' => !$entity->isNew(),
+      '#wrapper_attributes' => ['class' => ['entity-meta__title']],
+    ];
+    $form['meta']['changed'] = [
+      '#type' => 'item',
+      '#title' => $this->t('Last saved'),
+      '#markup' => !$entity->isNew() ? format_date($entity->getChangedTime(), 'short') : $this->t('Not saved yet'),
+      '#wrapper_attributes' => ['class' => ['entity-meta__last-saved']],
+    ];
+    $form['meta']['author'] = [
+      '#type' => 'item',
+      '#title' => $this->t('Author'),
+      '#markup' => $entity->getOwner()->getUsername(),
+      '#wrapper_attributes' => ['class' => ['entity-meta__author']],
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, FormStateInterface $form_state) {
+    $form_state->setRedirect('entity.eventseries.collection');
+
+    $entity = $this->getEntity();
+    $entity->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    // TODO: Add validation.
+    parent::validateForm($form, $form_state);
+  }
+
+}