diff --git a/src/Entity/WorkflowTransition.php b/src/Entity/WorkflowTransition.php
index 1f97c6537..e98c26d63 100644
--- a/src/Entity/WorkflowTransition.php
+++ b/src/Entity/WorkflowTransition.php
@@ -11,6 +11,7 @@
 use Drupal\user\Entity\User;
 use Drupal\user\UserInterface;
 use Drupal\workflow\WorkflowTypeAttributeTrait;
+use Drupal\workflow\Event\WorkflowTransitionEvent;

 /**
  * Implements an actual, executed, Transition.
@@ -92,6 +93,10 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition
   protected $is_executed;
   protected $is_forced = FALSE;

+  const PRE_TRANSITION = "pre_transition";
+
+  const POST_TRANSITION = "post_transition";
+
   /**
    * Entity class functions.
    */
@@ -508,7 +513,9 @@ public function execute($force = FALSE) {
       /*
        * Log the transition in {workflow_transition_scheduled}.
        */
+      $this->dispatchTransitionEvent($this::PRE_TRANSITION);
       $this->save();
+      $this->dispatchTransitionEvent($this::POST_TRANSITION);
     }
     else {
       // The transition is allowed, but not scheduled.
@@ -524,7 +531,9 @@ public function execute($force = FALSE) {
         /*
          * Log the transition in {workflow_transition_history}.
          */
+        $this->dispatchTransitionEvent($this::PRE_TRANSITION);
         $this->save();
+        $this->dispatchTransitionEvent($this::POST_TRANSITION);

         // Register state change with watchdog.
         if ($this->hasStateChange() && !empty($this->getWorkflow()->options['watchdog_log'])) {
@@ -616,6 +625,33 @@ private function _updateEntity() {
     $entity->save();
   }

+  /**
+   * Dispatches a transition event for the given phase.
+   *
+   * @param string $phase
+   *   The phase: pre_transition OR post_transition.
+   */
+  protected function dispatchTransitionEvent($phase) {
+
+    $workflow = $this->getWorkflow();
+
+    $event = new WorkflowTransitionEvent($this, $workflow, $this->getTargetEntity());
+    $event_dispatcher = \Drupal::getContainer()->get('event_dispatcher');
+
+    $events = [
+      // For example: 'my_custom_workflow.my_custom_transition.pre_transition'.
+      $this->getWorkflowId() . '.' . $this->getToSid() . '.' . $phase,
+      // For example: 'my_custom_workflow.pre_transition'.
+      $this->getWorkflowId() . '.' . $phase,
+      // For example: 'workflow.pre_transition'.
+      'workflow.' . $phase,
+    ];
+
+    foreach ($events as $event_id) {
+      $event_dispatcher->dispatch($event_id, $event);
+    }
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/src/Event/WorkflowTransitionEvent.php b/src/Event/WorkflowTransitionEvent.php
new file mode 100644
index 000000000..eceba0c65
--- /dev/null
+++ b/src/Event/WorkflowTransitionEvent.php
@@ -0,0 +1,133 @@
+<?php
+
+namespace Drupal\workflow\Event;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\workflow\Entity\WorkflowInterface;
+use Drupal\workflow\Entity\WorkflowTransition;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Defines the workflow transition event.
+ */
+class WorkflowTransitionEvent extends Event {
+
+  /**
+     * The transition.
+     *
+     * @var \Drupal\workflow\Entity\WorkflowTransition
+     */
+  protected $transition;
+
+  /**
+     * The workflow.
+     *
+     * @var \Drupal\workflow\Entity\WorkflowInterface
+     */
+  protected $workflow;
+
+  /**
+     * The entity.
+     *
+     * @var \Drupal\Core\Entity\ContentEntityInterface
+     */
+  protected $entity;
+
+  /**
+     * The state field name.
+     *
+     * @var string
+     */
+  //protected $fieldName;
+
+  /**
+     * Constructs a new WorkflowTransitionEvent object.
+     *
+     * @param \Drupal\workflow\Entity\WorkflowTransition $transition
+     *   The transition.
+     * @param \Drupal\workflow\Entity\WorkflowInterface $workflow
+     *   The workflow.
+     * @param \Drupal\Core\Entity\EntityInterface $entity
+     *   The entity.
+     */
+  public function __construct(WorkflowTransition $transition, WorkflowInterface $workflow, EntityInterface $entity) {
+        $this->transition = $transition;
+        $this->workflow = $workflow;
+        $this->entity = $entity;
+      }
+
+  /**
+     * Gets the transition.
+     *
+     * @return \Drupal\workflow\Entity\WorkflowTransition
+     *   The transition.
+     */
+  public function getTransition() {
+        return $this->transition;
+  }
+
+  /**
+     * Gets the workflow.
+     *
+     * @return \Drupal\workflow\Entity\WorkflowInterface
+     *   The workflow.
+     */
+  public function getWorkflow() {
+        return $this->workflow;
+  }
+
+  /**
+     * Gets the entity.
+     *
+     * @return \Drupal\Core\Entity\EntityInterface
+     *   The entity.
+     */
+  public function getEntity() {
+        return $this->entity;
+  }
+
+  /**
+     * Gets the state field name.
+     *
+     * @return string
+     *   The state field name.
+     */
+  /*public function getFieldName() {
+    return $this->fieldName;
+  }*/
+
+  /**
+     * Gets the state field.
+     *
+     * @return \Drupal\state_machine\Plugin\Field\FieldType\StateItemInterface
+     *   The state field.
+     */
+  /* public function getField() {
+     /** @var \Drupal\state_machine\Plugin\Field\FieldType\StateItemInterface $field * /
+     $field = $this->entity->get($this->fieldName)->first();
+     return $field;
+   }
+  */
+  /**
+     * Gets the "from" state.
+     *
+     * @return \Drupal\workflow\Entity\WorkflowState
+     *   The "from" state.
+     *
+     */
+  public function getFromState() {
+        return $this->transition->getFromState();
+  }
+
+  /**
+     * Gets the "to" state.
+     *
+     * @return \Drupal\workflow\Entity\WorkflowState
+     *   The "to" state.
+     *
+     */
+  public function getToState() {
+        return $this->transition->getToState();
+  }
+
+}
