diff --git a/client/components/history.vue b/client/components/history.vue
index b90fe13a..b22055f1 100644
--- a/client/components/history.vue
+++ b/client/components/history.vue
@@ -55,7 +55,7 @@
                         v-list-item(@click='download(ph.versionId)')
                           v-list-item-avatar(size='24'): v-icon mdi-cloud-download-outline
                           v-list-item-title Download Version
-                        v-list-item(@click='restore(ph.versionId)', :disabled='ph.versionId === 0')
+                        v-list-item(@click='restore(ph.versionId, ph.versionDate)', :disabled='ph.versionId === 0')
                           v-list-item-avatar(size='24'): v-icon(:disabled='ph.versionId === 0') mdi-history
                           v-list-item-title Restore
                         v-list-item(@click='branchOff(ph.versionId)')
@@ -111,6 +111,17 @@
                         .overline View Mode
                 v-card.mt-3(light, v-html='diffHTML', flat)
 
+    v-dialog(v-model='isRestoreConfirmDialogShown', max-width='650', persistent)
+      v-card
+        .dialog-header.is-orange {{$t('history:restore.confirmTitle')}}
+        v-card-text.pa-4
+          i18next(tag='span', path='history:restore.confirmText')
+            strong(place='date') {{ restoreTarget.versionDate | moment('LLL') }}
+        v-card-actions
+          v-spacer
+          v-btn(text, @click='isRestoreConfirmDialogShown = false', :disabled='restoreLoading') {{$t('common:actions.cancel')}}
+          v-btn(color='orange darken-2', dark, @click='restoreConfirm', :loading='restoreLoading') {{$t('history:restore.confirmButton')}}
+
     nav-footer
     notify
     search-results
@@ -124,6 +135,7 @@ import _ from 'lodash'
 import gql from 'graphql-tag'
 
 export default {
+  i18nOptions: { namespaces: 'history' },
   props: {
     pageId: {
       type: Number,
@@ -194,7 +206,13 @@ export default {
       offsetPage: 0,
       total: 0,
       viewMode: 'line-by-line',
-      cache: []
+      cache: [],
+      restoreTarget: {
+        versionId: 0,
+        versionDate: ''
+      },
+      isRestoreConfirmDialogShown: false,
+      restoreLoading: false
     }
   },
   computed: {
@@ -335,8 +353,59 @@ export default {
     download (versionId) {
       window.location.assign(`/d/${this.locale}/${this.path}?v=${versionId}`)
     },
-    restore (versionId) {
-
+    restore (versionId, versionDate) {
+      this.restoreTarget = {
+        versionId,
+        versionDate
+      }
+      this.isRestoreConfirmDialogShown = true
+    },
+    async restoreConfirm () {
+      this.restoreLoading = true
+      this.$store.commit(`loadingStart`, 'history-restore')
+      try {
+        const resp = await this.$apollo.mutate({
+          mutation: gql`
+            mutation ($pageId: Int!, $versionId: Int!) {
+              pages {
+                restore (pageId: $pageId, versionId: $versionId) {
+                  responseResult {
+                    succeeded
+                    errorCode
+                    slug
+                    message
+                  }
+                }
+              }
+            }
+          `,
+          variables: {
+            versionId: this.restoreTarget.versionId,
+            pageId: this.pageId
+          }
+        })
+        if (_.get(resp, 'data.pages.restore.responseResult.succeeded', false) === true) {
+          this.$store.commit('showNotification', {
+            style: 'success',
+            message: this.$t('history:restore.success'),
+            icon: 'check'
+          })
+          this.isRestoreConfirmDialogShown = false
+          setTimeout(() => {
+            window.location.assign(`/${this.locale}/${this.path}`)
+          }, 1000)
+        } else {
+          throw new Error(_.get(resp, 'data.pages.restore.responseResult.message', 'An unexpected error occured'))
+        }
+      } catch (err) {
+        this.$store.commit('showNotification', {
+          style: 'red',
+          message: err.message,
+          icon: 'alert'
+        })
+      }
+      this.$store.commit(`loadingStop`, 'history-restore')
+      this.restoreLoading = false
     },
     branchOff (versionId) {
 
diff --git a/server/graph/resolvers/page.js b/server/graph/resolvers/page.js
index 7039834d..7052d76d 100644
--- a/server/graph/resolvers/page.js
+++ b/server/graph/resolvers/page.js
@@ -385,7 +385,7 @@ module.exports = {
       try {
         const page = await WIKI.models.pages.query().findById(args.id)
         if (!page) {
-          throw new Error('Invalid Page Id')
+          throw new WIKI.Error.PageNotFound()
         }
         await WIKI.models.pages.renderPage(page)
         return {
@@ -394,6 +394,42 @@ module.exports = {
       } catch (err) {
         return graphHelper.generateError(err)
       }
+    },
+    /**
+     * RESTORE PAGE VERSION
+     */
+    async restore (obj, args, context) {
+      try {
+        const page = await WIKI.models.pages.query().select('path', 'localeCode').findById(args.pageId)
+        if (!page) {
+          throw new WIKI.Error.PageNotFound()
+        }
+
+        if (!WIKI.auth.checkAccess(context.req.user, ['write:pages'], {
+          path: page.path,
+          locale: page.localeCode
+        })) {
+          throw new WIKI.Error.PageRestoreForbidden()
+        }
+
+        const targetVersion = await WIKI.models.pageHistory.getVersion({ pageId: args.pageId, versionId: args.versionId })
+        if (!targetVersion) {
+          throw new WIKI.Error.PageNotFound()
+        }
+
+        await WIKI.models.pages.updatePage({
+          ...targetVersion,
+          id: targetVersion.pageId,
+          user: context.req.user,
+          action: 'restored'
+        })
+
+        return {
+          responseResult: graphHelper.generateSuccess('Page version restored successfully.')
+        }
+      } catch (err) {
+        return graphHelper.generateError(err)
+      }
     }
   },
   Page: {
diff --git a/server/graph/schemas/page.graphql b/server/graph/schemas/page.graphql
index f17daa01..0eb9b319 100644
--- a/server/graph/schemas/page.graphql
+++ b/server/graph/schemas/page.graphql
@@ -129,6 +129,11 @@ type PageMutation {
   render(
     id: Int!
   ): DefaultResponse @auth(requires: ["manage:system"])
+
+  restore(
+    pageId: Int!
+    versionId: Int!
+  ): DefaultResponse @auth(requires: ["write:pages", "manage:pages", "manage:system"])
 }
 
 # -----------------------------------------------
diff --git a/server/helpers/error.js b/server/helpers/error.js
index 560162be..c7da98fa 100644
--- a/server/helpers/error.js
+++ b/server/helpers/error.js
@@ -153,6 +153,10 @@ module.exports = {
     message: 'Destination page path already exists.',
     code: 6006
   }),
+  PageRestoreForbidden: CustomError('PageRestoreForbidden', {
+    message: 'You are not authorized to restore this page version.',
+    code: 6011
+  }),
   PageUpdateForbidden: CustomError('PageUpdateForbidden', {
     message: 'You are not authorized to update this page.',
     code: 6009
diff --git a/server/models/pages.js b/server/models/pages.js
index 21bce9f8..265cb767 100644
--- a/server/models/pages.js
+++ b/server/models/pages.js
@@ -326,7 +326,8 @@ module.exports = class Page extends Model {
     await WIKI.models.pageHistory.addVersion({
       ...ogPage,
       isPublished: ogPage.isPublished === true || ogPage.isPublished === 1,
-      action: 'updated'
+      action: opts.action ? opts.action : 'updated',
+      versionDate: ogPage.updatedAt
     })
 
     // -> Update page
@@ -422,7 +423,8 @@ module.exports = class Page extends Model {
     // -> Create version snapshot
     await WIKI.models.pageHistory.addVersion({
       ...page,
-      action: 'moved'
+      action: 'moved',
+      versionDate: page.updatedAt
     })
 
     const destinationHash = pageHelper.generateHash({ path: opts.destinationPath, locale: opts.destinationLocale, privateNS: opts.isPrivate ? 'TODO' : '' })
@@ -503,7 +505,8 @@ module.exports = class Page extends Model {
     // -> Create version snapshot
     await WIKI.models.pageHistory.addVersion({
       ...page,
-      action: 'deleted'
+      action: 'deleted',
+      versionDate: page.updatedAt
     })
 
     // -> Delete page