diff --git a/common/lib/xmodule/setup.py b/common/lib/xmodule/setup.py
index b3a8dabe1bf8a885667341acc1b25dc5ce9623b5..a405d111be03a74e5bf9c7e7f9e67f066d881abf 100644
--- a/common/lib/xmodule/setup.py
+++ b/common/lib/xmodule/setup.py
@@ -39,7 +39,8 @@ setup(
             "course_info = xmodule.html_module:CourseInfoDescriptor",
             "static_tab = xmodule.html_module:StaticTabDescriptor",
             "custom_tag_template = xmodule.raw_module:RawDescriptor",
-            "about = xmodule.html_module:AboutDescriptor"
+            "about = xmodule.html_module:AboutDescriptor",
+            "poll = xmodule.poll_module:PollDescriptor",
         ],
     }
 )
diff --git a/common/lib/xmodule/xmodule/js/src/poll/display.coffee b/common/lib/xmodule/xmodule/js/src/poll/display.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..f72ac8d3199f63801d3a1866832b64d53a5eedd5
--- /dev/null
+++ b/common/lib/xmodule/xmodule/js/src/poll/display.coffee
@@ -0,0 +1,13 @@
+class @PollModule
+  constructor: (element) ->
+    @el = element
+    @ajaxUrl = @$('.container').data('url')
+    @$('.upvote').on('click', () => $.postWithPrefix(@url('upvote'), @handleVote))
+    @$('.downvote').on('click', () => $.postWithPrefix(@url('downvote'), @handleVote))
+
+  $: (selector) -> $(selector, @el)
+
+  url: (target) -> "#{@ajaxUrl}/#{target}"
+
+  handleVote: (response) =>
+    @$('.container').replaceWith(response.results)
\ No newline at end of file
diff --git a/common/lib/xmodule/xmodule/poll_module.py b/common/lib/xmodule/xmodule/poll_module.py
new file mode 100644
index 0000000000000000000000000000000000000000..db0b3fd0c42b73ffa21c47aaf0842fd79f29a3d4
--- /dev/null
+++ b/common/lib/xmodule/xmodule/poll_module.py
@@ -0,0 +1,54 @@
+import json
+import logging
+
+from lxml import etree
+from pkg_resources import resource_string, resource_listdir
+
+from xmodule.x_module import XModule
+from xmodule.raw_module import RawDescriptor
+from .model import Int, Scope, Boolean
+
+log = logging.getLogger(__name__)
+
+
+class PollModule(XModule):
+
+    js = {'coffee': [resource_string(__name__, 'js/src/poll/display.coffee')]}
+    js_module_name = "PollModule"
+
+    upvotes = Int(help="Number of upvotes this poll has recieved", scope=Scope.content, default=0)
+    downvotes = Int(help="Number of downvotes this poll has recieved", scope=Scope.content, default=0)
+    voted = Boolean(help="Whether this student has voted on the poll", scope=Scope.student_state, default=False)
+
+    def handle_ajax(self, dispatch, get):
+        '''
+        Handle ajax calls to this video.
+        TODO (vshnayder): This is not being called right now, so the position
+        is not being saved.
+        '''
+        if self.voted:
+            return json.dumps({'error': 'Already Voted!'})
+        elif dispatch == 'upvote':
+            self.upvotes += 1
+            self.voted = True
+            return json.dumps({'results': self.get_html()})
+        elif dispatch == 'downvote':
+            self.downvotes += 1
+            self.voted = True
+            return json.dumps({'results': self.get_html()})
+
+        return json.dumps({'error': 'Unknown Command!'})
+
+    def get_html(self):
+        return self.system.render_template('poll.html', {
+            'upvotes': self.upvotes,
+            'downvotes': self.downvotes,
+            'voted': self.voted,
+            'ajax_url': self.system.ajax_url,
+        })
+
+
+class PollDescriptor(RawDescriptor):
+    module_class = PollModule
+    stores_state = True
+    template_dir_name = "poll"
\ No newline at end of file
diff --git a/common/test/data/toy/course/2012_Fall.xml b/common/test/data/toy/course/2012_Fall.xml
index 46dba8b8d8ab9621acb4f513d8c4d40981afe63d..31244ef60c1bee184e4b6f2404853512001ddec4 100644
--- a/common/test/data/toy/course/2012_Fall.xml
+++ b/common/test/data/toy/course/2012_Fall.xml
@@ -3,6 +3,7 @@
     <videosequence url_name="Toy_Videos">
       <html url_name="secret:toylab"/>
       <video url_name="Video_Resources" youtube="1.0:1bK-WdDi6Qw"/>
+      <poll url_name="test_poll" display_name="Test Poll"/>
     </videosequence>
     <video url_name="Welcome" youtube="1.0:p2Q6BrNhdh8"/>
     <video url_name="video_123456789012" youtube="1.0:p2Q6BrNhdh8"/>
diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py
index 04dee7de0fb1af076fa69be4917ba953dcddff05..c2a8db0fabe4182553162228d4ae9867c2d51aec 100644
--- a/lms/djangoapps/courseware/module_render.py
+++ b/lms/djangoapps/courseware/module_render.py
@@ -231,6 +231,18 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
         student_module.max_grade = event.get('max_value')
         student_module.save()
 
+        #Bin score into range and increment stats
+        score_bucket = get_score_bucket(student_module.grade, student_module.max_grade)
+        org, course_num, run = course_id.split("/")
+        statsd.increment("lms.courseware.question_answered",
+                        tags=["org:{0}".format(org),
+                              "course:{0}".format(course_num),
+                              "run:{0}".format(run),
+                              "score_bucket:{0}".format(score_bucket),
+                              "type:ajax"])
+
+
+
     # TODO (cpennington): When modules are shared between courses, the static
     # prefix is going to have to be specific to the module, not the directory
     # that the xml was loaded from
diff --git a/lms/templates/poll.html b/lms/templates/poll.html
new file mode 100644
index 0000000000000000000000000000000000000000..6ae2af50d1d288bcba0f8d00be26512befac70c8
--- /dev/null
+++ b/lms/templates/poll.html
@@ -0,0 +1,9 @@
+<div class='container' data-url="${ajax_url}">
+% if voted:
+    <div>Upvotes: ${upvotes}</div>
+    <div>Downvotes: ${downvotes}</div>
+% else:
+    <a class="upvote">Yes</a>
+    <a class="downvote">No</a>
+% endif
+</div>
\ No newline at end of file