diff --git a/cps.install b/cps.install
index 126d185..0f2fa75 100644
--- a/cps.install
+++ b/cps.install
@@ -622,3 +622,10 @@ function cps_update_7108() {
 
   db_add_field('cps_changeset', 'lock_in_select', $field);
 }
+
+/**
+ * Add index on revision_id.
+ */
+function cps_update_7109() {
+  db_add_index('cps_entity', 'revision_id', array('entity_type', 'revision_id'));
+}
diff --git a/cps.module b/cps.module
index 8f28aa6..5843d43 100644
--- a/cps.module
+++ b/cps.module
@@ -1401,6 +1401,19 @@ function cps_changeset_get_states() {
 }
 
 /**
+ * Fetch a list of possible states of a given type for changesets.
+ *
+ * @param string $type
+ *   Can be "open" or "closed".
+ *
+ * @return array
+ *   An array of state named keyed by the internal name.
+ */
+function cps_get_states_by_type($type) {
+  return array_filter(cps_changeset_get_states(), function ($state) use ($type) { return $state['type'] == $type; });
+}
+
+/**
  * Fetch the labels for all changeset states.
  *
  * @return string[]
diff --git a/cps_path/cps_path.info b/cps_path/cps_path.info
new file mode 100644
index 0000000..7ec533e
--- /dev/null
+++ b/cps_path/cps_path.info
@@ -0,0 +1,6 @@
+name = CPS path
+description = CPS path validation
+dependencies[] = path_revision
+package = cps
+core = 7.x
+
diff --git a/cps_path/cps_path.module b/cps_path/cps_path.module
new file mode 100644
index 0000000..35f65d3
--- /dev/null
+++ b/cps_path/cps_path.module
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file cps_path.module
+ */
+
+/**
+ * Implements hook_node_validate().
+ */
+function cps_path_node_validate($node) {
+  if (empty($node->path['alias'])) {
+    return;
+  }
+  $select = db_select('cps_changeset', 'c');
+  $select->addField('c', 'uid');
+  $select->join('cps_entity', 'ce', 'c.changeset_id = ce.changeset_id');
+  $select->join('path_revision', 'pr', 'ce.entity_type = pr.entity_type AND ce.revision_id = pr.revision_id');
+  $select
+    ->condition('c.changeset_id', cps_get_current_changeset(), '!=')
+    ->condition('c.status', array_keys(cps_get_states_by_type('open')))
+    ->condition('pr.alias', $node->path['alias']);
+  if (!empty($node->nid)) {
+    $or = db_or()
+      ->condition('ce.entity_type', 'node', '!=')
+      ->condition('ce.entity_id', $node->nid, '!=');
+    $select->condition($or);
+  }
+  $other_user = $select->execute()->fetchField();
+  if ($other_user) {
+    $args = array('@user' => format_username(user_load($other_user)));
+    form_set_error('path][alias', t('This alias is used in a changeset by @user', $args));
+  }
+}
