diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py
index b9c08b8232e289d72cce95a25178fe74c4430692..33049caffaa195025a4549645a9d63c66dfa9424 100644
--- a/addons/website_event/controllers/main.py
+++ b/addons/website_event/controllers/main.py
@@ -3,6 +3,8 @@
 import babel.dates
 import re
 import werkzeug
+import json
+
 from datetime import datetime, timedelta
 from dateutil.relativedelta import relativedelta
 
@@ -258,7 +260,23 @@ class WebsiteEventController(http.Controller):
             Attendees += Attendees.sudo().create(
                 Attendees._prepare_attendee_values(registration))
 
+        urls = event._get_event_resource_urls(Attendees.ids)
         return request.render("website_event.registration_complete", {
             'attendees': Attendees,
             'event': event,
+            'google_url': urls.get('google_url'),
+            'iCal_url': urls.get('iCal_url')
         })
+
+    @http.route(['/event/<model("event.event"):event>/ics/<string:name>.ics'], type='http', auth="public", website=True)
+    def make_event_ics_file(self, event, **kwargs):
+        if not event or not event.registration_ids:
+            return request.not_found()
+        attendee_ids = list(json.loads(kwargs.get('attendees', '{}').replace("'", '"')).values())
+        files = event.get_ics_file(attendee_ids)
+        content = files[event.id]
+        return request.make_response(content, [
+            ('Content-Type', 'application/octet-stream'),
+            ('Content-Length', len(content)),
+            ('Content-Disposition', 'attachment; filename=' + event.name + '.ics')
+        ])
diff --git a/addons/website_event/models/event.py b/addons/website_event/models/event.py
index cf5c2bbd872c7c8a84a9c94c536cfb18d34e1a38..573f8b34fbacba865526393671a3b20ebcdeca86 100644
--- a/addons/website_event/models/event.py
+++ b/addons/website_event/models/event.py
@@ -1,7 +1,26 @@
 # -*- coding: utf-8 -*-
 
+import logging
+import pytz
+import werkzeug
+
+from datetime import datetime
+
 from odoo import api, fields, models, _
 from odoo.addons.http_routing.models.ir_http import slug
+from odoo.exceptions import UserError
+from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
+
+_logger = logging.getLogger(__name__)
+
+try:
+    import vobject
+except ImportError:
+    _logger.warning("`vobject` Python module not found, iCal file generation disabled. Consider installing this module if you want to generate iCal files")
+    vobject = None
+
+GOOGLE_CALENDAR_URL = 'https://www.google.com/calendar/render?'
+
 
 class EventType(models.Model):
     _name = 'event.type'
@@ -115,3 +134,49 @@ class Event(models.Model):
             'target': 'new',
             'url': '/report/html/%s/%s?enable_editor' % ('event.event_event_report_template_badge', self.id),
         }
+
+    @api.multi
+    def get_ics_file(self, attendee_ids):
+        """ Returns iCalendar file for the event invitation.
+            :returns a dict of .ics file content for each event
+        """
+        result = {}
+        if not vobject:
+            return result
+
+        for event in self:
+            cal = vobject.iCalendar()
+            cal_event = cal.add('vevent')
+
+            if not event.date_begin or not event.date_end:
+                raise UserError(_("No date has been specified for the event, no file will be generated."))
+            cal_event.add('created').value = fields.Datetime.from_string(fields.Datetime.now()).replace(tzinfo=pytz.timezone('UTC'))
+            cal_event.add('dtstart').value = fields.Datetime.from_string(event.date_begin).replace(tzinfo=pytz.timezone('UTC'))
+            cal_event.add('dtend').value = fields.Datetime.from_string(event.date_end).replace(tzinfo=pytz.timezone('UTC'))
+            cal_event.add('summary').value = event.name
+            if event.address_id:
+                cal_event.add('location').value = event.sudo().address_id.contact_address
+
+            attendees = self.env['event.registration'].browse(attendee_ids)
+            for attendee in attendees:
+                attendee_add = cal_event.add('attendee')
+                attendee_add.value = u'MAILTO:' + (attendee.email or u'')
+            result[event.id] = cal.serialize().encode('utf-8')
+        return result
+
+    def _get_event_resource_urls(self, attendees):
+        url_date_start = datetime.strptime(self.date_begin, DEFAULT_SERVER_DATETIME_FORMAT).strftime('%Y%m%dT%H%M%SZ')
+        url_date_stop = datetime.strptime(self.date_end, DEFAULT_SERVER_DATETIME_FORMAT).strftime('%Y%m%dT%H%M%SZ')
+        params = werkzeug.url_encode({
+            'action': 'TEMPLATE',
+            'text': self.name,
+            'dates': url_date_start + '/' + url_date_stop,
+            'location': self.sudo().address_id.contact_address.replace('\n', ' '),
+            'details': self.name,
+        })
+        google_url = GOOGLE_CALENDAR_URL + params
+        params = werkzeug.url_encode({
+            'attendees': dict(('attendee_%s' % attendee, attendee) for attendee in attendees)
+        })
+        iCal_url = '/event/%s/ics/%s.ics?' % (slug(self), self.name) + params
+        return {'google_url': google_url, 'iCal_url': iCal_url}
diff --git a/addons/website_event/views/event_templates.xml b/addons/website_event/views/event_templates.xml
index 9a04d4e7e57d9445d4a6f217d47761b3f7b419f7..cf813068e97286bedb1eb24b5253a2bc8c65e510 100644
--- a/addons/website_event/views/event_templates.xml
+++ b/addons/website_event/views/event_templates.xml
@@ -594,6 +594,14 @@
                 <div class="col-md-9 mt16">
                     <h4><a t-attf-href="/event/#{slug(event)}"><t t-esc="event.name"/></a></h4>
                     <i class="fa fa-clock-o"></i> <span itemprop="startDate" t-esc="event.date_begin_located"> </span> <i>to</i> <span itemprop="endDate" t-esc="event.date_end_located"> </span>
+                    <div id="add_to_calendar" class="mt4">
+                        <a class="btn btn-primary mr8" t-att-href="iCal_url">
+                            <i class="fa fa-fw fa-arrow-right"/>Add to iCal/Outlook
+                        </a>
+                        <a class="btn btn-primary" t-att-href="google_url" target='_blank'>
+                            <i class="fa fa-fw fa-arrow-right"/>Add to Google Calendar
+                        </a>
+                    </div>
                     <div itemprop="location" class="mt16 mb8" t-field="event.address_id" t-options='{
                             "widget": "contact",
                             "fields": ["name", "address", "phone", "mobile", "email"]
diff --git a/addons/website_event_sale/controllers/main.py b/addons/website_event_sale/controllers/main.py
index 7ccb7f9e4b532b6f798357c24bab7c690110f495..25c32b88ccddb423ab75841760ae28cead2fac0c 100644
--- a/addons/website_event_sale/controllers/main.py
+++ b/addons/website_event_sale/controllers/main.py
@@ -42,9 +42,12 @@ class WebsiteEventSaleController(WebsiteEventController):
             attendees = request.env['event.registration'].browse(list(attendee_ids))
             # clean context and session, then redirect to the confirmation page
             request.website.sale_reset()
+            urls = event._get_event_resource_urls(list(attendee_ids))
             return request.render("website_event.registration_complete", {
                 'attendees': attendees,
                 'event': event,
+                'google_url': urls.get('google_url'),
+                'iCal_url': urls.get('iCal_url')
             })
 
         return request.redirect("/shop/checkout")